2018-12-31 20:04:05 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
require_once 'TlDocumentationGenerator.php';
|
|
|
|
|
|
|
|
class DoxygenTlDocumentationGenerator extends TlDocumentationGenerator
|
|
|
|
{
|
|
|
|
private function getParameterTypeName($type)
|
|
|
|
{
|
|
|
|
switch ($type) {
|
|
|
|
case 'Bool':
|
|
|
|
return 'bool ';
|
|
|
|
case 'int32':
|
|
|
|
return 'std::int32_t ';
|
|
|
|
case 'int53':
|
|
|
|
case 'int64':
|
|
|
|
return 'std::int64_t ';
|
|
|
|
case 'double':
|
|
|
|
return 'double ';
|
|
|
|
case 'string':
|
|
|
|
return 'std::string const &';
|
2020-03-24 18:02:03 +01:00
|
|
|
case 'bytes':
|
|
|
|
return 'bytes const &';
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
if (substr($type, 0, 6) === 'vector') {
|
|
|
|
if ($type[6] !== '<' || $type[strlen($type) - 1] !== '>') {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return 'std::vector<'.$this->getTypeName(substr($type, 7, -1)).'> &&';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (preg_match('/[^A-Za-z0-9.]/', $type)) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return 'object_ptr<'.$this->getClassName($type).'> &&';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function escapeDocumentation($doc)
|
|
|
|
{
|
|
|
|
$doc = htmlspecialchars($doc);
|
2019-12-25 17:16:43 +01:00
|
|
|
$doc = preg_replace_callback('/"((http|https|tg):\/\/[^" ]*)"/',
|
|
|
|
function ($quoted_link)
|
|
|
|
{
|
|
|
|
return ""<a href=\"".$quoted_link[1]."\">".$quoted_link[1]."</a>"";
|
|
|
|
}, $doc);
|
2018-12-31 20:04:05 +01:00
|
|
|
$doc = str_replace('*/', '*/', $doc);
|
|
|
|
$doc = str_replace('#', '\#', $doc);
|
|
|
|
return $doc;
|
|
|
|
}
|
|
|
|
|
2018-03-16 22:26:27 +01:00
|
|
|
protected function getFieldName($name, $class_name)
|
2018-12-31 20:04:05 +01:00
|
|
|
{
|
|
|
|
if (substr($name, 0, 6) === 'param_') {
|
|
|
|
$name = substr($name, 6);
|
|
|
|
}
|
|
|
|
return $name.'_';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getClassName($type)
|
|
|
|
{
|
2018-03-16 22:26:27 +01:00
|
|
|
return implode(explode('.', trim($type, "\r\n ;")));
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getTypeName($type)
|
|
|
|
{
|
|
|
|
switch ($type) {
|
|
|
|
case 'Bool':
|
|
|
|
return 'bool';
|
|
|
|
case 'int32':
|
|
|
|
return 'std::int32_t';
|
|
|
|
case 'int53':
|
|
|
|
case 'int64':
|
|
|
|
return 'std::int64_t';
|
|
|
|
case 'double':
|
|
|
|
return 'double';
|
|
|
|
case 'string':
|
|
|
|
return 'std::string';
|
2020-03-24 18:02:03 +01:00
|
|
|
case 'bytes':
|
|
|
|
return 'bytes';
|
2018-12-31 20:04:05 +01:00
|
|
|
case 'bool':
|
|
|
|
case 'int':
|
|
|
|
case 'long':
|
|
|
|
case 'Int':
|
|
|
|
case 'Long':
|
|
|
|
case 'Int32':
|
|
|
|
case 'Int53':
|
|
|
|
case 'Int64':
|
|
|
|
case 'Double':
|
|
|
|
case 'String':
|
|
|
|
case 'Bytes':
|
|
|
|
$this->printError("Wrong type $type");
|
|
|
|
return '';
|
|
|
|
default:
|
|
|
|
if (substr($type, 0, 6) === 'vector') {
|
|
|
|
if ($type[6] !== '<' || $type[strlen($type) - 1] !== '>') {
|
|
|
|
$this->printError("Wrong vector subtype in $type");
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return 'std::vector<'.$this->getTypeName(substr($type, 7, -1)).'>';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (preg_match('/[^A-Za-z0-9.]/', $type)) {
|
|
|
|
$this->printError("Wrong type $type");
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return 'object_ptr<'.$this->getClassName($type).'>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getBaseClassName($is_function)
|
|
|
|
{
|
|
|
|
return $is_function ? 'Function' : 'Object';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function needRemoveLine($line)
|
|
|
|
{
|
|
|
|
$line = trim($line);
|
|
|
|
return strpos($line, '/**') === 0 || strpos($line, '*') === 0 || strpos($line, '///') === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function needSkipLine($line)
|
|
|
|
{
|
|
|
|
$tline = trim($line);
|
2018-03-16 22:26:27 +01:00
|
|
|
return empty($tline) || $tline[0] === '}' || $tline === 'public:' || strpos($line, '#pragma ') === 0 ||
|
2018-12-31 20:04:05 +01:00
|
|
|
strpos($line, '#include <') === 0 || strpos($tline, 'return ') === 0 || strpos($tline, 'namespace') === 0 ||
|
2018-01-21 13:24:00 +01:00
|
|
|
preg_match('/class [A-Za-z0-9_]*;/', $line) || $tline === 'if (value == nullptr) {' ||
|
|
|
|
strpos($line, 'JNIEnv') || strpos($line, 'jfieldID') || $tline === 'virtual ~Object() {' ||
|
2018-03-16 22:26:27 +01:00
|
|
|
$tline === 'virtual void store(TlStorerToString &s, const char *field_name) const = 0;';
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function isHeaderLine($line)
|
|
|
|
{
|
|
|
|
return strpos($line, 'template <') === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function extractClassName($line)
|
|
|
|
{
|
|
|
|
if (strpos($line, 'class ') === 0) {
|
|
|
|
return explode(' ', trim($line))[1];
|
|
|
|
}
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function fixLine($line)
|
|
|
|
{
|
2018-01-21 13:24:00 +01:00
|
|
|
if (strpos($line, 'ID = ') > 0 || strpos($line, 'ReturnType = ') > 0 || strpos($line, 'using BaseObject = ') === 0) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return substr($line, 0, strpos($line, '='));
|
|
|
|
}
|
2018-01-21 13:24:00 +01:00
|
|
|
if (strpos($line, 'class Function: ') === 0) {
|
|
|
|
return 'class Function';
|
|
|
|
}
|
|
|
|
if (strpos($line, 'class Object {') === 0 || strpos($line, 'class Object: public TlObject {') === 0) {
|
|
|
|
return 'class Object';
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
return $line;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function addGlobalDocumentation()
|
|
|
|
{
|
|
|
|
$this->addDocumentation('#include "td/tl/TlObject.h"', <<<EOT
|
|
|
|
/**
|
|
|
|
* \\file
|
|
|
|
* Contains declarations of all functions and types which represent a public TDLib interface.
|
|
|
|
*/
|
|
|
|
EOT
|
2020-03-24 18:02:03 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('using bytes = std::string;', <<<EOT
|
|
|
|
/**
|
|
|
|
* This class is used to store arbitrary sequence of bytes.
|
|
|
|
*/
|
|
|
|
EOT
|
2018-12-31 20:04:05 +01:00
|
|
|
);
|
|
|
|
|
2018-01-21 13:24:00 +01:00
|
|
|
$this->addDocumentation('using BaseObject', <<<EOT
|
2018-12-31 20:04:05 +01:00
|
|
|
/**
|
|
|
|
* This class is a base class for all TDLib API classes and functions.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('using object_ptr = ::td::tl_object_ptr<Type>;', <<<EOT
|
|
|
|
/**
|
|
|
|
* A smart wrapper to store a pointer to a TDLib API object. Can be treated as an analogue of std::unique_ptr.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('object_ptr<Type> make_object(Args &&... args) {', <<<EOT
|
|
|
|
/**
|
|
|
|
* A function to create a dynamically allocated TDLib API object. Can be treated as an analogue of std::make_unique.
|
|
|
|
* Usage example:
|
|
|
|
* \\code
|
|
|
|
* auto get_authorization_state_request = td::td_api::make_object<td::td_api::getAuthorizationState>();
|
2018-01-30 18:06:54 +01:00
|
|
|
* auto message_text = td::td_api::make_object<td::td_api::formattedText>("Hello, world!!!",
|
2019-11-27 12:54:35 +01:00
|
|
|
* std::vector<td::td_api::object_ptr<td::td_api::textEntity>>());
|
2019-12-06 00:36:33 +01:00
|
|
|
* auto send_message_request = td::td_api::make_object<td::td_api::sendMessage>(chat_id, 0, nullptr, nullptr,
|
2018-01-30 18:06:54 +01:00
|
|
|
* td::td_api::make_object<td::td_api::inputMessageText>(std::move(message_text), false, true));
|
2018-12-31 20:04:05 +01:00
|
|
|
* \\endcode
|
|
|
|
*
|
|
|
|
* \\tparam Type Type of an object to construct.
|
|
|
|
* \\param[in] args Arguments to pass to the object constructor.
|
|
|
|
* \\return Wrapped pointer to the created object.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('object_ptr<ToType> move_object_as(FromType &&from) {', <<<EOT
|
|
|
|
/**
|
|
|
|
* A function to cast a wrapped in td::td_api::object_ptr TDLib API object to its subclass or superclass.
|
2019-03-25 00:07:31 +01:00
|
|
|
* Casting an object to an incorrect type will lead to undefined behaviour.
|
2018-12-31 20:04:05 +01:00
|
|
|
* Usage example:
|
|
|
|
* \\code
|
2018-01-21 13:24:00 +01:00
|
|
|
* td::td_api::object_ptr<td::td_api::callState> call_state = ...;
|
2018-12-31 20:04:05 +01:00
|
|
|
* switch (call_state->get_id()) {
|
|
|
|
* case td::td_api::callStatePending::ID: {
|
2018-01-21 13:24:00 +01:00
|
|
|
* auto state = td::td_api::move_object_as<td::td_api::callStatePending>(call_state);
|
2018-12-31 20:04:05 +01:00
|
|
|
* // use state
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* case td::td_api::callStateExchangingKeys::ID: {
|
|
|
|
* // no additional fields, no casting is needed
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* case td::td_api::callStateReady::ID: {
|
2018-01-21 13:24:00 +01:00
|
|
|
* auto state = td::td_api::move_object_as<td::td_api::callStateReady>(call_state);
|
2018-12-31 20:04:05 +01:00
|
|
|
* // use state
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* case td::td_api::callStateHangingUp::ID: {
|
|
|
|
* // no additional fields, no casting is needed
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* case td::td_api::callStateDiscarded::ID: {
|
2018-01-21 13:24:00 +01:00
|
|
|
* auto state = td::td_api::move_object_as<td::td_api::callStateDiscarded>(call_state);
|
2018-12-31 20:04:05 +01:00
|
|
|
* // use state
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* case td::td_api::callStateError::ID: {
|
2018-01-21 13:24:00 +01:00
|
|
|
* auto state = td::td_api::move_object_as<td::td_api::callStateError>(call_state);
|
2018-12-31 20:04:05 +01:00
|
|
|
* // use state
|
|
|
|
* break;
|
|
|
|
* }
|
|
|
|
* default:
|
|
|
|
* assert(false);
|
|
|
|
* }
|
|
|
|
* \\endcode
|
|
|
|
*
|
|
|
|
* \\tparam ToType Type of a TDLib API object to move to.
|
|
|
|
* \\tparam FromType Type of a TDLib API object to move from, this is auto-deduced.
|
|
|
|
* \\param[in] from Wrapped in td::td_api::object_ptr pointer to a TDLib API object.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('std::string to_string(const BaseObject &value);', <<<EOT
|
|
|
|
/**
|
|
|
|
* Returns a string representation of the TDLib API object.
|
|
|
|
* \\param[in] value The object.
|
|
|
|
* \\return Object string representation.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation('std::string to_string(const object_ptr<T> &value) {', <<<EOT
|
|
|
|
/**
|
|
|
|
* Returns a string representation of the TDLib API object.
|
|
|
|
* \\tparam T Object type, auto-deduced.
|
|
|
|
* \\param[in] value The object.
|
|
|
|
* \\return Object string representation.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation(' void store(TlStorerToString &s, const char *field_name) const final;', <<<EOT
|
|
|
|
/**
|
|
|
|
* Helper function for to_string method. Appends string representation of the object to the storer.
|
|
|
|
* \\param[in] s Storer to which object string representation will be appended.
|
|
|
|
* \\param[in] field_name Object field_name if applicable.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
2018-01-21 13:24:00 +01:00
|
|
|
$this->addDocumentation('class Object', <<<EOT
|
2018-12-31 20:04:05 +01:00
|
|
|
/**
|
|
|
|
* This class is a base class for all TDLib API classes.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
2018-01-21 13:24:00 +01:00
|
|
|
$this->addDocumentation('class Function', <<<EOT
|
2018-12-31 20:04:05 +01:00
|
|
|
/**
|
|
|
|
* This class is a base class for all TDLib API functions.
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation(' static const std::int32_t ID', <<<EOT
|
|
|
|
/// Identifier uniquely determining a type of the object.
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation(' std::int32_t get_id() const final {', <<<EOT
|
|
|
|
/**
|
|
|
|
* Returns identifier uniquely determining a type of the object.
|
|
|
|
* \\return this->ID.
|
|
|
|
*/
|
|
|
|
EOT
|
2018-06-25 16:23:56 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation(' virtual std::int32_t get_id() const = 0;', <<<EOT
|
|
|
|
/**
|
|
|
|
* Returns identifier uniquely determining a type of the object.
|
|
|
|
* \\return this->ID.
|
|
|
|
*/
|
|
|
|
EOT
|
2018-12-31 20:04:05 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->addDocumentation(' using ReturnType', <<<EOT
|
|
|
|
/// Typedef for the type returned by the function.
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function addAbstractClassDocumentation($class_name, $documentation)
|
|
|
|
{
|
|
|
|
$this->addDocumentation("class $class_name: public Object {", <<<EOT
|
|
|
|
/**
|
|
|
|
* This class is an abstract base class.
|
|
|
|
* $documentation
|
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-25 00:07:31 +01:00
|
|
|
protected function getFunctionReturnTypeDescription($return_type, $for_constructor)
|
2018-12-31 20:04:05 +01:00
|
|
|
{
|
2019-03-25 00:07:31 +01:00
|
|
|
$shift = $for_constructor ? ' ' : ' ';
|
|
|
|
return PHP_EOL.$shift.'*'.PHP_EOL.$shift."* Returns $return_type.";
|
2019-03-24 23:18:25 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2019-03-24 23:18:25 +01:00
|
|
|
protected function addClassDocumentation($class_name, $base_class_name, $description)
|
|
|
|
{
|
2018-12-31 20:04:05 +01:00
|
|
|
$this->addDocumentation("class $class_name final : public $base_class_name {", <<<EOT
|
|
|
|
/**
|
2019-03-24 23:18:25 +01:00
|
|
|
* $description
|
2018-12-31 20:04:05 +01:00
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function addFieldDocumentation($class_name, $field_name, $type_name, $field_info, $may_be_null)
|
|
|
|
{
|
|
|
|
$this->addDocumentation($class_name." $type_name $field_name;", <<<EOT
|
|
|
|
/// $field_info
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-25 00:07:31 +01:00
|
|
|
protected function addDefaultConstructorDocumentation($class_name, $class_description)
|
2018-12-31 20:04:05 +01:00
|
|
|
{
|
|
|
|
$this->addDocumentation(" $class_name();", <<<EOT
|
|
|
|
/**
|
2019-03-25 00:07:31 +01:00
|
|
|
* $class_description
|
2018-12-31 20:04:05 +01:00
|
|
|
*/
|
|
|
|
EOT
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-25 00:07:31 +01:00
|
|
|
protected function addFullConstructorDocumentation($class_name, $class_description, $known_fields, $info)
|
2018-12-31 20:04:05 +01:00
|
|
|
{
|
2018-03-16 22:26:27 +01:00
|
|
|
$explicit = count($known_fields) === 1 ? 'explicit ' : '';
|
2018-12-31 20:04:05 +01:00
|
|
|
$full_constructor = " $explicit$class_name(";
|
|
|
|
$colon = '';
|
|
|
|
foreach ($known_fields as $name => $type) {
|
2018-03-16 22:26:27 +01:00
|
|
|
$full_constructor .= $colon.$this->getParameterTypeName($type).$this->getFieldName($name, $class_name);
|
2018-12-31 20:04:05 +01:00
|
|
|
$colon = ', ';
|
|
|
|
}
|
|
|
|
$full_constructor .= ');';
|
|
|
|
|
|
|
|
$full_doc = <<<EOT
|
|
|
|
/**
|
2019-03-25 00:07:31 +01:00
|
|
|
* $class_description
|
2018-12-31 20:04:05 +01:00
|
|
|
*
|
|
|
|
|
|
|
|
EOT;
|
|
|
|
foreach ($known_fields as $name => $type) {
|
2018-03-16 22:26:27 +01:00
|
|
|
$full_doc .= ' * \\param[in] '.$this->getFieldName($name, $class_name).' '.$info[$name].PHP_EOL;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
$full_doc .= ' */';
|
|
|
|
$this->addDocumentation($full_constructor, $full_doc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$generator = new DoxygenTlDocumentationGenerator();
|
|
|
|
$generator->generate($argv[1], $argv[2]);
|