feat: parser now writes, added missing fields

updated docs, example, extensive use of Traits with better handling.
valid level 9 phpstan codebase.
This commit is contained in:
2024-08-18 18:23:05 +03:00
parent 8771b14d2a
commit aa6786981a
24 changed files with 406 additions and 296 deletions

View File

@@ -5,19 +5,18 @@
// run this file: php parser.php
$models = file_get_contents(sprintf('%s%2$smodels.txt', __DIR__, DIRECTORY_SEPARATOR));
// Capture the names as one group,
// and blocks inside curly braces as another,
// Capture the names as one group, and blocks inside curly braces as another,
// then combine them later.
preg_match_all("/(\w+)\s\{([\w\W]*?)\}/m", $models, $output_array);
[$all, $names, $fields] = $output_array;
$fields = array_map(function ($f) {
$f = explode("\n", $f);
$f = array_map("trim", $f);
$f = array_filter($f);
$fields = array_map(static function ($f) {
$d = explode("\n", $f);
$d = array_map("trim", $d);
$d = array_filter($d);
$f = array_map(function ($field) {
$d = array_map(static function ($field) {
[$name_and_type, $docs] = explode(":", $field, 2);
$names_and_types = explode(" ", $name_and_type, 2);
@@ -25,18 +24,21 @@ $fields = array_map(function ($f) {
$type = str_replace(["(", ")"], "", $type);
// Handle optional types.
if (str_contains($type, "optional")) {
$type = str_replace(["optional", ","], "", $type);
$type = "?" . trim($type);
}
// Handle integer types.
if ($type === "integer") {
$type = "int";
}
// Handle array types. Convert Array[Type] to Type[].
if (str_contains($type, "Array")) {
$type = str_replace(["Array[", "]"], "", $type);
$type = $type . "[]";
$type .= "[]";
}
$default = null;
@@ -60,62 +62,92 @@ $fields = array_map(function ($f) {
"default" => $default,
],
];
}, $f ?? []);
}, $d);
$f = array_merge(...$f);
return $f;
return array_merge(...$d);
}, $fields);
$classes = array_combine($names, $fields);
ksort($classes);
// print_r($classes);
// Files that have already been processed.
// Uncomment to display the results again.
$added = [
// "BisCompanyRegisteredOffice",
// "BisCompanyRegisteredEntry",
// "BisCompanyName",
// "BisCompanyLiquidation",
// "BisCompanyLanguage",
// "BisCompanyForm",
// "BisCompanyDetails",
// "BisCompanyContactDetail",
// "BisCompanyBusinessLine",
// "BisCompanyBusinessIdChange",
// "BisAddress",
];
$files = [];
// Output the classes as preformatted for easier copypasta.
// This is not the prettiest way to generate the codes, but it works.
foreach ($classes as $className => $vars) {
if (in_array($className, $added)) {
continue;
// Get name of the class from filename and split CamelCase to words.
$classNameString = $className;
$classNameString = str_replace("Bis", "", $classNameString);
$classNameString = preg_replace('/(?<!^)[A-Z]/', ' $0', $classNameString);
$classNameString = ucwords($classNameString);
$usesHeader = [
"",
"use Spatie\DataTransferObject\DataTransferObject;"
];
$hasCasters = [
"BisCompanyDetails",
];
if (in_array($className, $hasCasters, true)) {
$usesHeader["CastWith"] = "use Spatie\DataTransferObject\Attributes\CastWith;";
$usesHeader["Casters"] = "use Spatie\DataTransferObject\Casters;";
}
$traits = [];
if (array_key_exists('authority', $vars)) {
$traits[] = " use Traits\HasAuthority;";
}
if (array_key_exists('source', $vars)) {
$traits[] = " use Traits\HasSource;";
}
if (array_key_exists('version', $vars)) {
$traits[] = " use Traits\HasVersion;";
}
if (array_key_exists('language', $vars)) {
$traits[] = " use Traits\HasLanguage;";
}
if (array_key_exists('change', $vars)) {
$traits[] = " use Traits\HasChange;";
}
if (array_key_exists('register', $vars)) {
$traits[] = " use Traits\HasRegister;";
}
echo "
if (!empty($traits)) {
$usesHeader[] = "use Ivuorinen\BusinessDataFetcher\Traits;";
}
$usesString = implode("\n", $usesHeader);
$used = ['authority', 'source', 'version', 'language', 'change', 'register'];
$file = "<?php
namespace Ivuorinen\BusinessDataFetcher\Dto;
$usesString
/**
* $className
* $classNameString
*/
class $className extends DataTransferObject
{
";
if (array_key_exists("source", $vars)) {
echo " use HasSource;\n";
{";
if (!empty($traits)) {
$file .= "\n" . implode("\n", $traits) . "\n";
}
foreach ($vars as $varKey => $varData) {
if ($varKey === "source") {
if (in_array($varKey, $used, true)) {
continue;
}
$caster = "";
if (str_contains($varData["type"], "[")) {
$classType = str_replace(["[", "]", "?"], "", $varData["type"]);
$caster = "\n #[CastWith(Casters\ArrayCaster::class, itemType: {$classType}::class)]";
$caster = "\n #[CastWith(Casters\ArrayCaster::class, itemType: $classType::class)]";
}
$type = $varData["type"];
@@ -126,12 +158,33 @@ class $className extends DataTransferObject
}
$default = $varData["default"] !== null ? " = " . $varData["default"] . ";" : ";";
echo "
$file .= "
/**
* {$varData["docs"]}{$typeHelper}
*/{$caster}
public {$type} \${$varData["name"]}{$default}
public $type \${$varData["name"]}{$default}
";
}
echo "\n}";
$file .= "}\n";
$files[$className] = $file;
}
if (!empty($files)) {
echo "Generating files:\n";
foreach ($files as $className => $file) {
$filePath = sprintf(
'%s%s%s%s%s%s%s.php',
dirname(__FILE__, 2),
DIRECTORY_SEPARATOR,
'src',
DIRECTORY_SEPARATOR,
'Dto',
DIRECTORY_SEPARATOR,
$className
);
echo $filePath . "\n";
file_put_contents($filePath, $file);
}
}