Skip to content

Commit

Permalink
feat: add load model node caster
Browse files Browse the repository at this point in the history
  • Loading branch information
yusuftaufiq committed Apr 19, 2022
1 parent 02fe6bf commit 7ecbaa1
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 94 deletions.
114 changes: 114 additions & 0 deletions src/Casts/AbstractMethodCallNodeCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

namespace Haemanthus\CodeIgniter3IdeHelper\Casts;

use Haemanthus\CodeIgniter3IdeHelper\Objects\PropertyTagDTO;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Cast\Array_;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;

abstract class AbstractMethodCallNodeCast extends AbstractNodeCast
{
protected static $classCategory;

protected static $classParameterName;

protected static $aliasParameterName;

protected static $classParameterPosition;

protected static $aliasParameterPosition;

protected function classTypeOf(string $name): string
{
if (array_key_exists($name, $this->map[static::$classCategory] ?? []) === true) {
return $this->map[static::$classCategory][$name];
}

return $name;
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return array<Arg>
*/
protected function sortArguments(array $args): array
{
$key = 0;

return array_reduce($args, function (array $carry, Arg $arg) use (&$key): array {
switch (true) {
case $arg->name instanceof Identifier === false:
$carry[$key] = $arg;
break;

case $arg->name->name === static::$classParameterName:
$carry[static::$classParameterPosition] = $arg;
break;

case $arg->name->name === static::$aliasParameterName:
$carry[static::$classParameterPosition] = $arg;
break;
}

$key += 1;

return $carry;
}, []);
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return bool
*/
protected function isArgumentsTypeScalarString(array $args): bool
{
return array_reduce($args, fn (bool $carry, Arg $arg): bool => (
($arg->name === null || $arg->name instanceof Identifier)
&& ($arg->value instanceof String_ || $arg->value instanceof ConstFetch)
&& $carry
), true);
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return bool
*/
public function isArgumentsTypeExpressionArray(array $args): bool
{
return array_reduce($args, fn (bool $carry, Arg $arg): bool => (
($arg->name === null || $arg->name instanceof Identifier)
&& ($arg->value instanceof Array_)
&& $carry
), true);
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return ?PropertyTagDTO
*/
protected function castScalarStringArguments(array $args): ?PropertyTagDTO
{
if (array_key_exists(static::$classParameterPosition, $args) === false) {
return null;
}

$className = $args[static::$classParameterPosition]->value->value;
$hasAlias = array_key_exists(static::$aliasParameterPosition, $args);
$propertyAlias = $hasAlias ? $args[static::$aliasParameterPosition]->value->value : null;
$propertyName = $propertyAlias ?? $className;
$propertyType = $this->classTypeOf($className);

return new PropertyTagDTO($propertyName, $propertyType);
}
}
97 changes: 6 additions & 91 deletions src/Casts/LoadLibraryNodeCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,106 +5,21 @@
use Haemanthus\CodeIgniter3IdeHelper\Objects\PropertyTagDTO;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;

class LoadLibraryNodeCast extends AbstractNodeCast
class LoadLibraryNodeCast extends AbstractMethodCallNodeCast
{
protected const KEY = 'libraries';
protected static $classCategory = 'libraries';

protected function classTypeOf(string $name): string
{
if (array_key_exists($name, $this->map[self::KEY]) === true) {
return $this->map[self::KEY][$name];
}
protected static $classParameterName = 'library';

return $name;
}
protected static $aliasParameterName = 'object_name';

/**
* Undocumented function
*
* @param array<Arg> $args
* @return bool
*/
protected function isArgumentsTypeScalarString(array $args): bool
{
return array_reduce($args, fn (bool $carry, Arg $arg): bool => (
($arg->name === null || $arg->name instanceof Identifier)
&& ($arg->value instanceof String_ || $arg->value instanceof ConstFetch)
&& $carry
), true);
}
protected static $classParameterPosition = 0;

/**
* Undocumented function
*
* @param array<Arg> $args
* @return bool
*/
public function isArgumentsTypeExpressionArray(array $args): bool
{
return array_reduce($args, fn (bool $carry, Arg $arg): bool => (
($arg->name === null || $arg->name instanceof Identifier)
&& ($arg->value instanceof Array_)
&& $carry
), true);
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return array<Arg>
*/
protected function sortArguments(array $args): array
{
$key = 0;

return array_reduce($args, function (array $carry, Arg $arg) use (&$key): array {
switch (true) {
case $arg->name instanceof Identifier === false:
$carry[$key] = $arg;
break;

case $arg->name->name === 'library':
$carry[0] = $arg;
break;

case $arg->name->name === 'object_name':
$carry[2] = $arg;
break;
}

$key += 1;

return $carry;
}, []);
}

/**
* Undocumented function
*
* @param array<Arg> $args
* @return ?PropertyTagDTO
*/
protected function castScalarStringArguments(array $args): ?PropertyTagDTO
{
if (array_key_exists(0, $args) === false) {
return null;
}

$libraryClass = $args[0]->value->value;
$propertyAlias = array_key_exists(2, $args) ? $args[2]->value->value : null;
$propertyName = $propertyAlias ?? $libraryClass;
$propertyType = $this->classTypeOf($libraryClass);

return new PropertyTagDTO($propertyName, $propertyType);
}
protected static $aliasParameterPosition = 2;

protected function castExpressionArrayItem(ArrayItem $item): ?PropertyTagDTO
{
Expand Down
44 changes: 44 additions & 0 deletions src/Casts/LoadModelNodeCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Haemanthus\CodeIgniter3IdeHelper\Casts;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;

class LoadModelNodeCast extends AbstractMethodCallNodeCast
{
protected static $classCategory = 'models';

protected static $classParameterName = 'model';

protected static $aliasParameterName = 'name';

protected static $classParameterPosition = 0;

protected static $aliasParameterPosition = 1;

protected function classTypeOf(string $name): string
{
$path = explode('/', $name);
$modelName = $path[array_key_last($path)];

return $modelName;
}

public function cast(Node $node): array
{
$args = $node instanceof MethodCall ? $node->getArgs() : [];

switch (true) {
case $this->isArgumentsTypeScalarString($args):
$blocks = [$this->castScalarStringArguments($this->sortArguments($args))];
break;

default:
$blocks = [];
break;
}

return $blocks;
}
}
18 changes: 15 additions & 3 deletions src/Parsers/CoreFileParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Haemanthus\CodeIgniter3IdeHelper\Parsers;

use Haemanthus\CodeIgniter3IdeHelper\Casts\LoadLibraryNodeCast;
use Haemanthus\CodeIgniter3IdeHelper\Casts\LoadModelNodeCast;
use Haemanthus\CodeIgniter3IdeHelper\Visitors\ClassNodeVisitor;
use Haemanthus\CodeIgniter3IdeHelper\Visitors\MethodCallNodeVisitor;
use PhpParser\Node\Expr\MethodCall;
Expand All @@ -17,17 +18,21 @@ class CoreFileParser extends AbstractFileParser

protected LoadLibraryNodeCast $libraryCast;

protected LoadModelNodeCast $modelCast;

public function __construct(
ParserFactory $parser,
NodeTraverser $traverser,
ClassNodeVisitor $classVisitor,
MethodCallNodeVisitor $methodCallVisitor,
LoadLibraryNodeCast $libraryCast
LoadLibraryNodeCast $libraryCast,
LoadModelNodeCast $modelCast
) {
parent::__construct($parser, $traverser);
$this->classVisitor = $classVisitor;
$this->methodCallVisitor = $methodCallVisitor;
$this->libraryCast = $libraryCast;
$this->modelCast = $modelCast;

$this->traverser->addVisitor($this->classVisitor);
$this->traverser->addVisitor($this->methodCallVisitor);
Expand All @@ -46,8 +51,15 @@ public function parse(string $contents): array
[],
);

$models = $this->methodCallVisitor->getFoundLoadModelNodes();
$models = array_reduce(
$this->methodCallVisitor->getFoundLoadModelNodes(),
fn (array $carry, MethodCall $library): array => array_merge(
$carry,
$this->modelCast->cast($library),
),
[],
);

return array_merge($libraries);
return array_merge($libraries, $models);
}
}

0 comments on commit 7ecbaa1

Please sign in to comment.