2017-01-22 17:40:56 +01:00
< ? php
2018-02-24 17:54:13 +01:00
Merge alpha into master (async, huge bugfixes and more) (#546)
* Implement async and lots of bugfixes
* Implement more async
* Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr
* Apply fixes from StyleCI
* Bugfixes
* Apply fixes from StyleCI
* Bugfixes, implement combined promises
* Apply fixes from StyleCI
* Support passing method arguments as callable
* Starting to write async upload logic
* Apply fixes from StyleCI
* Start implementing async file upload
* Apply fixes from StyleCI
* bugfix
* Apply fixes from StyleCI
* Start rewriting connection module
* Add PHP file docblocks for all classes
* Start working on new async stream API
* Finish writing stream API
* More stream API fixes
* Apply fixes from StyleCI
* Rewrite DataCenter and Connection modules
* Clean up stream API documentation
* Fixes
* Apply fixes from StyleCI
* Add referenced parameter to get length of buffer to read in getReadBuffer API
* Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar
* Start fixing reads
* Fix all protocol stream wrappers
* Apply fixes from StyleCI
* Implement disconnection, and remove end function
* Working async RPC
* Implement async file upload
* Bugfix
* Method recall bugfixes
* Bugfixes
* Trait bugfixes
* Fix FIFO buffer
* Bugfixes and speedtests
* Async logging
* Implement websocket streams
* Implement loop API, signal API, clean closing and start changing layer
* Small magna, websocket and HTTP fixes
* Clean up loop API
* Improved stack traces, 2FA and async
* Login fixes
* Added instructions for manual verification
* Small fixes
* More app info improvements
* More app info improvements
* TL and 2FA fixes
* Update to layer 89
* More bugfixes
* Implement broken media reporting
* Remove debug comments
* PHP 7.2 backwards compatibility
* Bugfixes
* Async key generation
* Some simplifications
* Transport fixes
* Cleanup
* async API
* Performance fixes
* Fixes to async API
* Bugfixes
* Implement one-time async loop
* Authorization and logging fixes
* Update to layer 91
* 7to5 fix
* Null coalesce conversion
* Implement socks5 proxy
* Implement HTTP proxy
* Fixes to HTTP proxy
* MTProxy and socks5 fixes
* Disable PHP 5 conversion
* Proxies have higher priority
* Avoid error handling in vendor
* Override composer dependencies
* Fix travis build
* Final composer fixes
* Proxy logic fixes
* Fix get_updates update handling
* Do not use parallel file driver if not supported
* Refactor loader and implement HTTP fixes
* Suppress errors in loader
* HTTP and authorization fixes
* HTTP fixes
* Improved peer management
* Use HTTP protocol on altervista
* Small bugfixes
* Minor fixes
* Docufix
* Docufix
* Legacy fixes
* Fix message queue
* Avoid updating if using MTProxy
* Improve logs and examples
* Trim final newlines while converting parse mode
* Reimplement noResponse flag
* Async combined event handler and APIFactory fixes
* Actually return config
* Case-insensitive methods
* Bugfix
* Apply fixes from StyleCI (#545)
* MTProxy fixes
* PHP 5 warning
* Improved PHP 5 warning
* Use <br> along with newlines in web logs
* Update docs
2018-12-26 20:51:14 +01:00
/**
* AnnotationsBuilder module .
*
* This file is part of MadelineProto .
* MadelineProto is free software : you can redistribute it and / or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation , either version 3 of the License , or ( at your option ) any later version .
* MadelineProto is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU Affero General Public License for more details .
* You should have received a copy of the GNU General Public License along with MadelineProto .
* If not , see < http :// www . gnu . org / licenses />.
*
* @ author Daniil Gentili < daniil @ daniil . it >
2020-02-17 14:13:46 +01:00
* @ copyright 2016 - 2020 Daniil Gentili < daniil @ daniil . it >
Merge alpha into master (async, huge bugfixes and more) (#546)
* Implement async and lots of bugfixes
* Implement more async
* Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr
* Apply fixes from StyleCI
* Bugfixes
* Apply fixes from StyleCI
* Bugfixes, implement combined promises
* Apply fixes from StyleCI
* Support passing method arguments as callable
* Starting to write async upload logic
* Apply fixes from StyleCI
* Start implementing async file upload
* Apply fixes from StyleCI
* bugfix
* Apply fixes from StyleCI
* Start rewriting connection module
* Add PHP file docblocks for all classes
* Start working on new async stream API
* Finish writing stream API
* More stream API fixes
* Apply fixes from StyleCI
* Rewrite DataCenter and Connection modules
* Clean up stream API documentation
* Fixes
* Apply fixes from StyleCI
* Add referenced parameter to get length of buffer to read in getReadBuffer API
* Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar
* Start fixing reads
* Fix all protocol stream wrappers
* Apply fixes from StyleCI
* Implement disconnection, and remove end function
* Working async RPC
* Implement async file upload
* Bugfix
* Method recall bugfixes
* Bugfixes
* Trait bugfixes
* Fix FIFO buffer
* Bugfixes and speedtests
* Async logging
* Implement websocket streams
* Implement loop API, signal API, clean closing and start changing layer
* Small magna, websocket and HTTP fixes
* Clean up loop API
* Improved stack traces, 2FA and async
* Login fixes
* Added instructions for manual verification
* Small fixes
* More app info improvements
* More app info improvements
* TL and 2FA fixes
* Update to layer 89
* More bugfixes
* Implement broken media reporting
* Remove debug comments
* PHP 7.2 backwards compatibility
* Bugfixes
* Async key generation
* Some simplifications
* Transport fixes
* Cleanup
* async API
* Performance fixes
* Fixes to async API
* Bugfixes
* Implement one-time async loop
* Authorization and logging fixes
* Update to layer 91
* 7to5 fix
* Null coalesce conversion
* Implement socks5 proxy
* Implement HTTP proxy
* Fixes to HTTP proxy
* MTProxy and socks5 fixes
* Disable PHP 5 conversion
* Proxies have higher priority
* Avoid error handling in vendor
* Override composer dependencies
* Fix travis build
* Final composer fixes
* Proxy logic fixes
* Fix get_updates update handling
* Do not use parallel file driver if not supported
* Refactor loader and implement HTTP fixes
* Suppress errors in loader
* HTTP and authorization fixes
* HTTP fixes
* Improved peer management
* Use HTTP protocol on altervista
* Small bugfixes
* Minor fixes
* Docufix
* Docufix
* Legacy fixes
* Fix message queue
* Avoid updating if using MTProxy
* Improve logs and examples
* Trim final newlines while converting parse mode
* Reimplement noResponse flag
* Async combined event handler and APIFactory fixes
* Actually return config
* Case-insensitive methods
* Bugfix
* Apply fixes from StyleCI (#545)
* MTProxy fixes
* PHP 5 warning
* Improved PHP 5 warning
* Use <br> along with newlines in web logs
* Update docs
2018-12-26 20:51:14 +01:00
* @ license https :// opensource . org / licenses / AGPL - 3.0 AGPLv3
*
2019-10-31 15:07:35 +01:00
* @ link https :// docs . madelineproto . xyz MadelineProto documentation
Merge alpha into master (async, huge bugfixes and more) (#546)
* Implement async and lots of bugfixes
* Implement more async
* Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr
* Apply fixes from StyleCI
* Bugfixes
* Apply fixes from StyleCI
* Bugfixes, implement combined promises
* Apply fixes from StyleCI
* Support passing method arguments as callable
* Starting to write async upload logic
* Apply fixes from StyleCI
* Start implementing async file upload
* Apply fixes from StyleCI
* bugfix
* Apply fixes from StyleCI
* Start rewriting connection module
* Add PHP file docblocks for all classes
* Start working on new async stream API
* Finish writing stream API
* More stream API fixes
* Apply fixes from StyleCI
* Rewrite DataCenter and Connection modules
* Clean up stream API documentation
* Fixes
* Apply fixes from StyleCI
* Add referenced parameter to get length of buffer to read in getReadBuffer API
* Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar
* Start fixing reads
* Fix all protocol stream wrappers
* Apply fixes from StyleCI
* Implement disconnection, and remove end function
* Working async RPC
* Implement async file upload
* Bugfix
* Method recall bugfixes
* Bugfixes
* Trait bugfixes
* Fix FIFO buffer
* Bugfixes and speedtests
* Async logging
* Implement websocket streams
* Implement loop API, signal API, clean closing and start changing layer
* Small magna, websocket and HTTP fixes
* Clean up loop API
* Improved stack traces, 2FA and async
* Login fixes
* Added instructions for manual verification
* Small fixes
* More app info improvements
* More app info improvements
* TL and 2FA fixes
* Update to layer 89
* More bugfixes
* Implement broken media reporting
* Remove debug comments
* PHP 7.2 backwards compatibility
* Bugfixes
* Async key generation
* Some simplifications
* Transport fixes
* Cleanup
* async API
* Performance fixes
* Fixes to async API
* Bugfixes
* Implement one-time async loop
* Authorization and logging fixes
* Update to layer 91
* 7to5 fix
* Null coalesce conversion
* Implement socks5 proxy
* Implement HTTP proxy
* Fixes to HTTP proxy
* MTProxy and socks5 fixes
* Disable PHP 5 conversion
* Proxies have higher priority
* Avoid error handling in vendor
* Override composer dependencies
* Fix travis build
* Final composer fixes
* Proxy logic fixes
* Fix get_updates update handling
* Do not use parallel file driver if not supported
* Refactor loader and implement HTTP fixes
* Suppress errors in loader
* HTTP and authorization fixes
* HTTP fixes
* Improved peer management
* Use HTTP protocol on altervista
* Small bugfixes
* Minor fixes
* Docufix
* Docufix
* Legacy fixes
* Fix message queue
* Avoid updating if using MTProxy
* Improve logs and examples
* Trim final newlines while converting parse mode
* Reimplement noResponse flag
* Async combined event handler and APIFactory fixes
* Actually return config
* Case-insensitive methods
* Bugfix
* Apply fixes from StyleCI (#545)
* MTProxy fixes
* PHP 5 warning
* Improved PHP 5 warning
* Use <br> along with newlines in web logs
* Update docs
2018-12-26 20:51:14 +01:00
*/
2018-02-24 17:54:39 +01:00
2017-01-22 17:40:56 +01:00
namespace danog\MadelineProto ;
2019-09-18 21:49:26 +02:00
use Amp\Promise ;
2020-09-24 20:49:34 +02:00
use danog\MadelineProto\Settings\TLSchema ;
2019-10-31 20:48:06 +01:00
use danog\MadelineProto\TL\TL ;
2019-12-28 16:07:09 +01:00
use danog\MadelineProto\TL\TLCallback ;
2017-01-22 17:40:56 +01:00
use phpDocumentor\Reflection\DocBlockFactory ;
2018-02-24 17:54:39 +01:00
2017-01-22 17:40:56 +01:00
class AnnotationsBuilder
{
2020-10-03 12:36:08 +02:00
/**
2020-10-03 15:04:35 +02:00
* Reflection classes .
2020-10-03 12:36:08 +02:00
*/
private array $reflectionClasses = [];
/**
2020-10-03 15:04:35 +02:00
* Logger .
2020-10-03 12:36:08 +02:00
*/
private Logger $logger ;
/**
2020-10-03 15:04:35 +02:00
* Namespace .
2020-10-03 12:36:08 +02:00
*/
private string $namespace ;
/**
2020-10-03 15:04:35 +02:00
* TL instance .
2020-10-03 12:36:08 +02:00
*/
private TL $TL ;
/**
2020-10-03 15:04:35 +02:00
* Settings .
2020-10-03 12:36:08 +02:00
*/
private array $settings ;
/**
2020-10-03 15:04:35 +02:00
* Output file .
2020-10-03 12:36:08 +02:00
*/
private string $output ;
2019-12-14 16:47:04 +01:00
public function __construct ( Logger $logger , array $settings , string $output , array $reflectionClasses , string $namespace )
2017-01-22 17:40:56 +01:00
{
2019-12-14 16:47:04 +01:00
$this -> reflectionClasses = $reflectionClasses ;
2018-04-19 19:56:52 +02:00
$this -> logger = $logger ;
2019-12-14 16:47:04 +01:00
$this -> namespace = $namespace ;
2020-10-03 15:36:03 +02:00
/** @psalm-suppress InvalidArgument */
2019-10-31 20:48:06 +01:00
$this -> TL = new TL ( new class ( $logger ) {
2020-10-04 16:35:33 +02:00
public Logger $logger ;
public function __construct ( Logger $logger )
2019-10-31 20:48:06 +01:00
{
$this -> logger = $logger ;
}
});
2020-09-24 20:49:34 +02:00
$tlSchema = new TLSchema ;
$tlSchema -> mergeArray ( $settings );
$this -> TL -> init ( $tlSchema );
2017-01-22 17:40:56 +01:00
$this -> settings = $settings ;
2019-12-14 16:47:04 +01:00
$this -> output = $output ;
2017-01-22 17:40:56 +01:00
}
2020-10-01 21:03:25 +02:00
public function mkAnnotations () : void
2017-01-22 17:40:56 +01:00
{
2018-03-02 01:38:10 +01:00
\danog\MadelineProto\Logger :: log ( 'Generating annotations...' , \danog\MadelineProto\Logger :: NOTICE );
2017-01-22 17:40:56 +01:00
$this -> setProperties ();
$this -> createInternalClasses ();
}
/**
* Open file of class APIFactory
* Insert properties
* save the file with new content .
2019-09-13 16:55:48 +02:00
*
* @ return void
2017-01-22 17:40:56 +01:00
*/
private function setProperties ()
{
2018-03-02 01:38:10 +01:00
\danog\MadelineProto\Logger :: log ( 'Generating properties...' , \danog\MadelineProto\Logger :: NOTICE );
2017-01-22 17:40:56 +01:00
$fixture = DocBlockFactory :: createInstance ();
2019-12-14 16:47:04 +01:00
$class = new \ReflectionClass ( $this -> reflectionClasses [ 'APIFactory' ]);
2019-09-02 17:08:36 +02:00
$content = \file_get_contents ( $filename = $class -> getFileName ());
2017-01-22 17:40:56 +01:00
foreach ( $class -> getProperties () as $property ) {
if ( $raw_docblock = $property -> getDocComment ()) {
$docblock = $fixture -> create ( $raw_docblock );
if ( $docblock -> hasTag ( 'internal' )) {
2020-04-05 15:33:01 +02:00
$content = \str_replace ( " \n " . $raw_docblock . " \n public \$ " . $property -> getName () . ';' , '' , $content );
2017-01-22 17:40:56 +01:00
}
}
}
2019-10-31 20:48:06 +01:00
foreach ( $this -> TL -> getMethodNamespaces () as $namespace ) {
2020-04-05 15:33:01 +02:00
$content = \preg_replace ( '/(class( \\w+[,]?){0,}\\n{\\n)/' , '${1}' . " /** \n " . " * @internal this is a internal property generated by build_docs.php, don't change manually \n " . " * \n " . " * @var { $namespace } \n " . " */ \n " . " public \$ { $namespace } ; \n " , $content );
2017-01-22 17:40:56 +01:00
}
2019-09-02 17:08:36 +02:00
\file_put_contents ( $filename , $content );
2017-01-22 17:40:56 +01:00
}
/**
2019-12-28 16:07:09 +01:00
* Create internalDoc .
*
* @ return void
2017-01-22 17:40:56 +01:00
*/
2019-12-28 16:07:09 +01:00
private function createInternalClasses () : void
2017-01-22 17:40:56 +01:00
{
2018-03-02 01:38:10 +01:00
\danog\MadelineProto\Logger :: log ( 'Creating internal classes...' , \danog\MadelineProto\Logger :: NOTICE );
2019-12-14 16:47:04 +01:00
$handle = \fopen ( $this -> output , 'w' );
\fwrite ( $handle , " <?php namespace { $this -> namespace } ; class InternalDoc extends APIFactory { } " );
$class = new \ReflectionClass ( $this -> reflectionClasses [ 'API' ]);
2019-09-18 21:21:34 +02:00
$methods = $class -> getMethods ( \ReflectionMethod :: IS_STATIC | \ReflectionMethod :: IS_PUBLIC );
2019-12-28 17:34:04 +01:00
$ignoreMethods = [ 'fetchserializableobject' ];
2019-09-18 21:21:34 +02:00
foreach ( $methods as $method ) {
$ignoreMethods [ $method -> getName ()] = $method -> getName ();
}
2019-12-28 16:07:09 +01:00
$class = new \ReflectionClass ( TLCallback :: class );
$methods = $class -> getMethods ( \ReflectionMethod :: IS_STATIC | \ReflectionMethod :: IS_PUBLIC );
foreach ( $methods as $method ) {
$ignoreMethods [ $method -> getName ()] = $method -> getName ();
}
2019-09-18 21:21:34 +02:00
\fclose ( $handle );
2019-12-14 16:47:04 +01:00
$handle = \fopen ( $this -> output , 'w' );
2019-09-18 20:46:20 +02:00
$internalDoc = [];
2019-10-31 20:48:06 +01:00
foreach ( $this -> TL -> getMethods () -> by_id as $id => $data ) {
2019-09-02 17:08:36 +02:00
if ( ! \strpos ( $data [ 'method' ], '.' )) {
2017-01-22 17:40:56 +01:00
continue ;
}
2019-09-02 17:08:36 +02:00
list ( $namespace , $method ) = \explode ( '.' , $data [ 'method' ]);
2019-10-31 20:48:06 +01:00
if ( ! \in_array ( $namespace , $this -> TL -> getMethodNamespaces ())) {
2017-01-22 17:40:56 +01:00
continue ;
}
2020-06-16 17:52:55 +02:00
$internalDoc [ $namespace ][ $method ][ 'title' ] = \str_replace ([ '](../' , '.md' ], [ '](https://docs.madelineproto.xyz/API_docs/' , '.html' ], Lang :: $lang [ 'en' ][ " method_ { $data [ 'method' ] } " ] ? ? '' );
2019-12-14 16:47:04 +01:00
$type = \str_ireplace ([ 'vector<' , '>' ], [ ' of ' , '[]' ], $data [ 'type' ]);
2017-08-18 18:10:30 +02:00
foreach ( $data [ 'params' ] as $param ) {
2019-09-18 20:46:20 +02:00
if ( \in_array ( $param [ 'name' ], [ 'flags' , 'random_id' , 'random_bytes' ])) {
2017-01-22 17:40:56 +01:00
continue ;
}
2019-09-18 20:46:20 +02:00
if ( $param [ 'name' ] === 'data' && $type === 'messages.SentEncryptedMessage' ) {
$param [ 'name' ] = 'message' ;
$param [ 'type' ] = 'DecryptedMessage' ;
}
if ( $param [ 'name' ] === 'chat_id' && $data [ 'method' ] !== 'messages.discardEncryption' ) {
$param [ 'type' ] = 'InputPeer' ;
}
if ( $param [ 'name' ] === 'hash' && $param [ 'type' ] === 'int' ) {
$param [ 'pow' ] = 'hi' ;
$param [ 'type' ] = 'Vector t' ;
$param [ 'subtype' ] = 'int' ;
}
2017-01-22 17:40:56 +01:00
$stype = 'type' ;
if ( isset ( $param [ 'subtype' ])) {
$stype = 'subtype' ;
}
2019-12-14 16:47:04 +01:00
$ptype = $param [ $stype ];
2017-01-22 17:40:56 +01:00
switch ( $ptype ) {
case 'true' :
case 'false' :
$ptype = 'boolean' ;
}
2020-01-31 19:29:43 +01:00
$ptype = $stype === 'type' ? $ptype : " [ { $ptype } ] " ;
$opt = $param [ 'pow' ] ? ? false ? 'Optional: ' : '' ;
2020-06-16 17:52:55 +02:00
$internalDoc [ $namespace ][ $method ][ 'attr' ][ $param [ 'name' ]] = [ 'type' => $ptype , 'description' => \str_replace ([ '](../' , '.md' ], [ '](https://docs.madelineproto.xyz/API_docs/' , '.html' ], $opt . ( Lang :: $lang [ 'en' ][ " method_ { $data [ 'method' ] } _param_ { $param [ 'name' ] } _type_ { $param [ 'type' ] } " ] ? ? '' ))];
2017-01-22 17:40:56 +01:00
}
2017-01-27 13:19:16 +01:00
if ( $type === 'Bool' ) {
2019-09-02 17:08:36 +02:00
$type = \strtolower ( $type );
2017-01-22 17:40:56 +01:00
}
$internalDoc [ $namespace ][ $method ][ 'return' ] = $type ;
}
2019-12-14 16:47:04 +01:00
$class = new \ReflectionClass ( $this -> reflectionClasses [ 'MTProto' ]);
2019-09-18 20:46:20 +02:00
$methods = $class -> getMethods ( \ReflectionMethod :: IS_STATIC | \ReflectionMethod :: IS_PUBLIC );
2020-04-05 14:57:33 +02:00
$class = new \ReflectionClass ( Tools :: class );
$methods = \array_merge ( $methods , $class -> getMethods ( \ReflectionMethod :: IS_STATIC | \ReflectionMethod :: IS_PUBLIC ));
2019-09-18 21:21:34 +02:00
foreach ( $methods as $key => $method ) {
2019-09-18 20:46:20 +02:00
$name = $method -> getName ();
2019-10-29 22:41:31 +01:00
if ( $method == 'methodCallAsyncRead' ) {
unset ( $methods [ \array_search ( 'methodCall' , $methods )]);
2019-09-18 21:21:34 +02:00
} elseif ( \strpos ( $name , '__' ) === 0 ) {
unset ( $methods [ $key ]);
2019-09-18 20:46:20 +02:00
} elseif ( \stripos ( $name , 'async' ) !== false ) {
if ( \strpos ( $name , '_async' ) !== false ) {
unset ( $methods [ \array_search ( \str_ireplace ( '_async' , '' , $method ), $methods )]);
} else {
unset ( $methods [ \array_search ( \str_ireplace ( 'async' , '' , $method ), $methods )]);
}
}
}
2020-04-05 15:33:01 +02:00
$sortedMethods = [];
foreach ( $methods as $method ) {
$sortedMethods [ $method -> getName ()] = $method ;
}
\ksort ( $sortedMethods );
$methods = \array_values ( $sortedMethods );
2019-09-18 20:46:20 +02:00
foreach ( $methods as $method ) {
$name = $method -> getName ();
2019-09-18 21:21:34 +02:00
if ( isset ( $ignoreMethods [ $name ])) {
continue ;
}
2019-12-28 16:07:09 +01:00
if ( \strpos ( $method -> getDocComment () ? ? '' , '@internal' ) !== false ) {
continue ;
}
2019-12-28 16:45:00 +01:00
$static = $method -> isStatic ();
if ( ! $static ) {
$code = \file_get_contents ( $method -> getFileName ());
$code = \implode ( " \n " , \array_slice ( \explode ( " \n " , $code ), $method -> getStartLine (), $method -> getEndLine () - $method -> getStartLine ()));
if ( \strpos ( $code , '$this' ) === false ) {
2020-01-31 19:29:43 +01:00
Logger :: log ( " { $name } should be STATIC! " , Logger :: FATAL_ERROR );
2019-12-28 16:45:00 +01:00
}
}
2019-10-29 22:41:31 +01:00
if ( $name == 'methodCallAsyncRead' ) {
$name = 'methodCall' ;
2019-09-18 20:46:20 +02:00
} elseif ( \stripos ( $name , 'async' ) !== false ) {
if ( \strpos ( $name , '_async' ) !== false ) {
$name = \str_ireplace ( '_async' , '' , $name );
} else {
$name = \str_ireplace ( 'async' , '' , $name );
}
}
2020-06-16 17:52:55 +02:00
$name = StrTools :: toCamelCase ( $name );
2019-09-18 21:21:34 +02:00
$name = \str_ireplace ([ 'mtproto' , 'api' ], [ 'MTProto' , 'API' ], $name );
2019-09-18 20:46:20 +02:00
$doc = 'public function ' ;
$doc .= $name ;
$doc .= '(' ;
$paramList = '' ;
2019-09-18 21:21:34 +02:00
$hasVariadic = false ;
2019-09-18 20:46:20 +02:00
foreach ( $method -> getParameters () as $param ) {
if ( $param -> allowsNull ()) {
//$doc .= '?';
}
if ( $type = $param -> getType ()) {
if ( $type -> allowsNull ()) {
$doc .= '?' ;
}
2019-09-18 21:21:34 +02:00
if ( ! $type -> isBuiltin ()) {
$doc .= '\\' ;
}
2019-09-18 20:46:20 +02:00
$doc .= $type -> getName ();
$doc .= ' ' ;
2019-12-28 17:11:08 +01:00
} else {
2020-04-05 15:33:01 +02:00
Logger :: log ( $name . '.' . $param -> getName () . " has no type! " , Logger :: WARNING );
2019-09-18 20:46:20 +02:00
}
if ( $param -> isVariadic ()) {
$doc .= '...' ;
}
if ( $param -> isPassedByReference ()) {
$doc .= '&' ;
}
$doc .= '$' ;
$doc .= $param -> getName ();
if ( $param -> isOptional () && ! $param -> isVariadic ()) {
$doc .= ' = ' ;
if ( $param -> isDefaultValueConstant ()) {
2020-04-05 15:33:01 +02:00
$doc .= '\\' . \str_replace ([ 'NULL' , 'self' ], [ 'null' , 'danog\\MadelineProto\\MTProto' ], $param -> getDefaultValueConstantName ());
2019-09-18 20:46:20 +02:00
} else {
2019-09-18 21:21:34 +02:00
$doc .= \str_replace ( 'NULL' , 'null' , \var_export ( $param -> getDefaultValue (), true ));
2019-09-18 20:46:20 +02:00
}
}
$doc .= ', ' ;
2019-09-18 21:21:34 +02:00
if ( $param -> isVariadic ()) {
$hasVariadic = true ;
$paramList .= '...' ;
}
2020-04-05 15:33:01 +02:00
$paramList .= '$' . $param -> getName () . ', ' ;
2019-09-18 20:46:20 +02:00
}
2020-01-19 13:46:49 +01:00
$hasReturnValue = ( $type = $method -> getReturnType ()) && ! \in_array ( $type -> getName (), [ \Generator :: class , Promise :: class ]);
if ( ! $hasVariadic && ! $static && ! $hasReturnValue ) {
2019-09-18 21:45:08 +02:00
$paramList .= '$extra, ' ;
$doc .= 'array $extra = []' ;
}
2019-09-18 20:46:20 +02:00
$doc = \rtrim ( $doc , ', ' );
$paramList = \rtrim ( $paramList , ', ' );
$doc .= " ) " ;
2019-12-28 16:45:00 +01:00
$async = true ;
2020-10-06 20:37:11 +02:00
if ( $hasReturnValue && $static ) {
2019-09-18 20:46:20 +02:00
$doc .= ': ' ;
if ( $type -> allowsNull ()) {
$doc .= '?' ;
}
2019-12-28 16:45:00 +01:00
if ( ! $type -> isBuiltin ()) {
$doc .= '\\' ;
}
2020-01-19 13:46:49 +01:00
$doc .= $type -> getName () === 'self' ? $this -> reflectionClasses [ 'API' ] : $type -> getName ();
2019-12-28 16:45:00 +01:00
$async = false ;
2019-09-18 20:46:20 +02:00
}
2020-04-05 15:33:01 +02:00
if ( $method -> getDeclaringClass () -> getName () == Tools :: class ) {
$async = false ;
}
2020-01-31 19:29:43 +01:00
$finalParamList = $hasVariadic ? " Tools::arr( { $paramList } ) " : " [ { $paramList } ] " ;
2020-01-19 13:46:49 +01:00
$ret = $type && \in_array ( $type -> getName (), [ 'self' , 'void' ]) ? '' : 'return' ;
2020-01-03 13:09:42 +01:00
$doc .= " \n { \n " ;
2020-01-19 13:46:49 +01:00
if ( $async ) {
2020-01-31 19:29:43 +01:00
$doc .= " { $ret } \$ this->__call(__FUNCTION__, { $finalParamList } ); \n " ;
2020-01-19 13:46:49 +01:00
} elseif ( ! $static ) {
2020-01-31 19:29:43 +01:00
$doc .= " { $ret } \$ this->API-> { $name } ( { $paramList } ); \n " ;
2019-12-28 16:45:00 +01:00
} else {
2020-04-05 15:33:01 +02:00
$doc .= " { $ret } \\ " . $method -> getDeclaringClass () -> getName () . " :: " . $name . " ( { $paramList } ); \n " ;
2019-12-28 16:45:00 +01:00
}
2020-01-19 13:46:49 +01:00
if ( ! $ret && $type -> getName () === 'self' ) {
$doc .= " return \$ this; \n " ;
}
2020-01-03 13:09:42 +01:00
$doc .= " } \n " ;
2019-12-28 16:07:09 +01:00
if ( ! $method -> getDocComment ()) {
2020-01-31 19:29:43 +01:00
Logger :: log ( " { $name } has no PHPDOC! " , Logger :: FATAL_ERROR );
2019-12-28 16:07:09 +01:00
}
if ( ! $type ) {
2020-01-31 19:29:43 +01:00
Logger :: log ( " { $name } has no return type! " , Logger :: FATAL_ERROR );
2019-12-28 16:07:09 +01:00
}
2020-10-03 15:04:35 +02:00
$promise = '\\' . Promise :: class ;
$phpdoc = $method -> getDocComment () ? ? '' ;
$phpdoc = \str_replace ( " @return \\ Generator " , " @return $promise " , $phpdoc );
2020-10-06 20:37:11 +02:00
if ( $hasReturnValue && $async && \preg_match ( " /@return (.*)/ " , $phpdoc , $matches )) {
$ret = $matches [ 1 ];
$new = $ret ;
if ( $type && ! str_contains ( $ret , '<' )) {
$new = '' ;
if ( $type -> allowsNull ()) {
$new .= '?' ;
}
if ( ! $type -> isBuiltin ()) {
$new .= '\\' ;
}
$new .= $type -> getName () === 'self' ? $this -> reflectionClasses [ 'API' ] : $type -> getName ();
}
$phpdoc = \str_replace ( " @return " . $ret , " @return mixed " , $phpdoc );
if ( ! str_contains ( $phpdoc , '@psalm-return' )) {
$phpdoc = \str_replace ( " @return " , " @psalm-return $new | $promise < $new > \n * @return " , $phpdoc );
}
}
2020-10-03 15:04:35 +02:00
$phpdoc = \preg_replace (
" /@psalm-return \\ \\ Generator<(?:[^,]+), (?:[^,]+), (?:[^,]+), (.+)>/ " ,
" @psalm-return $promise < $ 1> " ,
$phpdoc
);
$internalDoc [ 'InternalDoc' ][ $name ][ 'method' ] = $phpdoc ;
2020-04-05 15:33:01 +02:00
$internalDoc [ 'InternalDoc' ][ $name ][ 'method' ] .= " \n " . \implode ( " \n " , \explode ( " \n " , $doc ));
2019-09-18 20:46:20 +02:00
}
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " <?php \n " );
\fwrite ( $handle , " /** \n " );
\fwrite ( $handle , " * This file is automatic generated by build_docs.php file \n " );
\fwrite ( $handle , " * and is used only for autocomplete in multiple IDE \n " );
\fwrite ( $handle , " * don't modify manually. \n " );
\fwrite ( $handle , " */ \n \n " );
2019-12-14 16:47:04 +01:00
\fwrite ( $handle , " namespace { $this -> namespace } ; \n " );
2017-01-22 17:40:56 +01:00
foreach ( $internalDoc as $namespace => $methods ) {
2019-09-18 20:46:20 +02:00
if ( $namespace === 'InternalDoc' ) {
\fwrite ( $handle , " \n class { $namespace } extends APIFactory \n { \n " );
} else {
\fwrite ( $handle , " \n interface { $namespace } \n { " );
}
2017-01-22 17:40:56 +01:00
foreach ( $methods as $method => $properties ) {
2019-09-18 20:46:20 +02:00
if ( isset ( $properties [ 'method' ])) {
\fwrite ( $handle , $properties [ 'method' ]);
continue ;
}
2019-12-28 16:45:00 +01:00
$title = \implode ( " \n * " , \explode ( " \n " , $properties [ 'title' ]));
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " \n /** \n " );
2019-12-28 16:45:00 +01:00
\fwrite ( $handle , " * { $title } \n " );
2019-09-18 20:46:20 +02:00
\fwrite ( $handle , " * \n " );
2017-01-22 17:40:56 +01:00
if ( isset ( $properties [ 'attr' ])) {
2019-09-18 20:46:20 +02:00
\fwrite ( $handle , " * Parameters: \n " );
$longest = [ 0 , 0 , 0 ];
foreach ( $properties [ 'attr' ] as $name => $param ) {
$longest [ 0 ] = \max ( $longest [ 0 ], \strlen ( $param [ 'type' ]));
$longest [ 1 ] = \max ( $longest [ 1 ], \strlen ( $name ));
$longest [ 2 ] = \max ( $longest [ 2 ], \strlen ( $param [ 'description' ]));
}
foreach ( $properties [ 'attr' ] as $name => $param ) {
2020-04-05 15:33:01 +02:00
$param [ 'type' ] = \str_pad ( '`' . $param [ 'type' ] . '`' , $longest [ 0 ] + 2 );
$name = \str_pad ( '**' . $name . '**' , $longest [ 1 ] + 4 );
2019-09-18 20:46:20 +02:00
$param [ 'description' ] = \str_pad ( $param [ 'description' ], $longest [ 2 ]);
\fwrite ( $handle , " * * { $param [ 'type' ] } { $name } - { $param [ 'description' ] } \n " );
2017-01-22 17:40:56 +01:00
}
2019-09-18 20:46:20 +02:00
\fwrite ( $handle , " * \n " );
\fwrite ( $handle , " * @param array \$ params Parameters \n " );
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " * \n " );
2017-01-22 17:40:56 +01:00
}
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " * @return { $properties [ 'return' ] } \n " );
\fwrite ( $handle , " */ \n " );
\fwrite ( $handle , " public function { $method } ( " );
2017-01-22 17:40:56 +01:00
if ( isset ( $properties [ 'attr' ])) {
2019-09-18 20:46:20 +02:00
\fwrite ( $handle , '$params' );
2017-01-22 17:40:56 +01:00
}
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " ); \n " );
2017-01-22 17:40:56 +01:00
}
2019-09-02 17:08:36 +02:00
\fwrite ( $handle , " } \n " );
2017-01-22 17:40:56 +01:00
}
2019-09-02 17:08:36 +02:00
\fclose ( $handle );
2017-01-22 17:40:56 +01:00
}
2018-02-24 17:54:39 +01:00
}