Improved code readability, added abstract classes support

This commit is contained in:
Sys 2021-07-29 23:27:46 +02:00
parent cad00a6155
commit 5b38b081c3
No known key found for this signature in database
GPG Key ID: 3CD2C29F8AB39BFD
2 changed files with 56 additions and 28 deletions

View File

@ -4,6 +4,7 @@
namespace TgScraper\Common;
use JetBrains\PhpStorm\ArrayShape;
use PHPHtmlParser\Dom;
use PHPHtmlParser\Exceptions\ChildNotFoundException;
use PHPHtmlParser\Exceptions\CircularException;
@ -41,6 +42,40 @@ class SchemaExtractor
{
}
/**
* @throws ParentNotFoundException
* @throws ChildNotFoundException
*/
#[ArrayShape(['description' => "string", 'table' => "mixed", 'extended_by' => "array"])]
private function parseNode(Dom\Node\AbstractNode $node): ?array
{
$description = '';
$table = null;
$extendedBy = [];
$tag = '';
$sibling = $node;
while (!str_starts_with($tag, 'h')) {
$sibling = $sibling->nextSibling();
$tag = $sibling?->tag?->name();
if (empty($node->text()) or empty($tag) or $tag == 'text') {
continue;
} elseif ($tag == 'p') {
$description .= PHP_EOL . $sibling->innerHtml();
} elseif ($tag == 'ul') {
$items = $sibling->find('li');
/* @var Dom\Node\AbstractNode $item */
foreach ($items as $item) {
$extendedBy[] = $item->innerText;
}
break;
} elseif ($tag == 'table') {
$table = $sibling->find('tbody')->find('tr');
break;
}
}
return ['description' => $description, 'table' => $table, 'extended_by' => $extendedBy];
}
/**
* @return array
* @throws ChildNotFoundException
@ -74,32 +109,12 @@ class SchemaExtractor
if (!str_contains($name = $element->text, ' ')) {
$isMethod = lcfirst($name) == $name;
$path = $isMethod ? 'methods' : 'types';
$temp = $element;
$description = '';
$table = null;
while (true) {
try {
$element = $element->nextSibling();
} catch (ChildNotFoundException) {
break;
}
$tag = $element->tag->name() ?? null;
if (empty($temp->text()) or empty($tag) or $tag == 'text') {
continue;
} elseif (str_starts_with($tag, 'h')) {
break;
} elseif ($tag == 'p') {
$description .= PHP_EOL . $element->innerHtml();
} elseif ($tag == 'table') {
$table = $element->find('tbody')->find('tr');
break;
}
}
/* @var Dom\Node\AbstractNode $element */
['description' => $description, 'table' => $table, 'extended_by' => $extendedBy] = self::parseNode($element);
$data[$path][] = self::generateElement(
$name,
trim($description),
$table,
$extendedBy,
$isMethod
);
}
@ -111,6 +126,7 @@ class SchemaExtractor
* @param string $name
* @param string $description
* @param Dom\Node\Collection|null $unparsedFields
* @param array $extendedBy
* @param bool $isMethod
* @return array
* @throws ChildNotFoundException
@ -124,13 +140,15 @@ class SchemaExtractor
string $name,
string $description,
?Dom\Node\Collection $unparsedFields,
array $extendedBy,
bool $isMethod
): array {
$fields = self::parseFields($unparsedFields, $isMethod);
$result = [
'name' => $name,
'description' => htmlspecialchars_decode(strip_tags($description), ENT_QUOTES),
'fields' => $fields
'fields' => $fields,
'extended_by' => $extendedBy
];
if ($isMethod) {
$returnTypes = self::parseReturnTypes($description);

View File

@ -19,6 +19,7 @@ use Nette\PhpGenerator\Type;
class StubCreator
{
/**
* @var string
*/
@ -115,13 +116,19 @@ class StubCreator
* @param string $namespace
* @return PhpFile[]
*/
#[ArrayShape(['Response' => "\Nette\PhpGenerator\PhpFile"])]
#[ArrayShape([
'Response' => "\Nette\PhpGenerator\PhpFile",
'TypeInterface' => "\Nette\PhpGenerator\ClassType"
])]
private function generateDefaultTypes(
string $namespace
): array {
$file = new PhpFile;
$phpNamespace = $file->addNamespace($namespace);
$response = $phpNamespace->addClass('Response')
$interfaceFile = new PhpFile;
$interfaceNamespace = $interfaceFile->addNamespace($namespace);
$interface = $interfaceNamespace->addInterface('TypeInterface');
$responseFile = new PhpFile;
$responseNamespace = $responseFile->addNamespace($namespace);
$response = $responseNamespace->addClass('Response')
->setType('class');
$response->addProperty('ok')
->setPublic()
@ -141,8 +148,10 @@ class StubCreator
->setType(Type::STRING)
->setNullable(true)
->setValue(null);
$response->addImplement($namespace . '\\TypeInterface');
return [
'Response' => $file
'Response' => $responseFile,
'TypeInterface' => $interfaceFile
];
}
@ -158,6 +167,7 @@ class StubCreator
$phpNamespace = $file->addNamespace($namespace);
$typeClass = $phpNamespace->addClass($type['name'])
->setType('class');
$typeClass->addImplement($namespace . '\\TypeInterface');
foreach ($type['fields'] as $field) {
['types' => $fieldTypes, 'comments' => $fieldComments] = $this->parseFieldTypes(
$field['types'],