updae:基于AST重构代码生成
This commit is contained in:
@@ -1,26 +1,46 @@
|
||||
<?php
|
||||
namespace catcher\generate\build;
|
||||
|
||||
use catcher\CatchAdmin;
|
||||
use catcher\facade\FileSystem;
|
||||
use catcher\generate\build\classes\Classes;
|
||||
use PhpParser\BuilderFactory;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
class PHPBuild
|
||||
class CatchBuild
|
||||
{
|
||||
protected $astBuilder;
|
||||
|
||||
protected $outPath;
|
||||
|
||||
protected $filename;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->astBuilder = app(BuilderFactory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 命名空间
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param string $namespace
|
||||
* @return $this
|
||||
*/
|
||||
public function namespace(string $namespace)
|
||||
{
|
||||
$this->astBuilder = $this->astBuilder->namespace('god');
|
||||
$this->astBuilder = $this->astBuilder->namespace($namespace);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* use 方法体
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param $use
|
||||
* @return $this
|
||||
*/
|
||||
public function use($use)
|
||||
{
|
||||
$this->astBuilder->addStmt($use);
|
||||
@@ -29,21 +49,93 @@ class PHPBuild
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* class 模版
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param Classes $class
|
||||
* @param \Closure $function
|
||||
* @return $this
|
||||
*/
|
||||
public function class(Classes $class, \Closure $function)
|
||||
{
|
||||
$function($class);
|
||||
|
||||
$this->astBuilder->addStmt($class->build());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param $condition
|
||||
* @param \Closure $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function when($condition, \Closure $closure)
|
||||
{
|
||||
if ($condition && $closure instanceof \Closure) {
|
||||
$closure($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
$stmts = array($this->astBuilder->getNode());
|
||||
|
||||
$prettyPrinter = new Standard();
|
||||
|
||||
return $prettyPrinter->prettyPrintFile($stmts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
return FileSystem::put($this->outPath . $this->filename, $this->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出 Path
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param $path
|
||||
* @return $this
|
||||
*/
|
||||
public function path($path)
|
||||
{
|
||||
CatchAdmin::makeDirectory($path);
|
||||
|
||||
$this->outPath = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function finish()
|
||||
/**
|
||||
* 设置文件名
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function filename($name)
|
||||
{
|
||||
$stmts = array($this->astBuilder->getNode());
|
||||
$prettyPrinter = new Standard();
|
||||
dd($prettyPrinter->prettyPrintFile($stmts));
|
||||
$this->filename = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,17 +1,27 @@
|
||||
<?php
|
||||
namespace catcher\generate\classes;
|
||||
namespace catcher\generate\build\classes;
|
||||
|
||||
class Classes extends Iteration
|
||||
use PhpParser\BuilderFactory;
|
||||
|
||||
class Classes
|
||||
{
|
||||
protected $classBuild;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->classBuild = (new BuilderFactory())->class($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 comment
|
||||
*
|
||||
* @time 2020年11月17日
|
||||
* @param $name
|
||||
* @time 2020年11月19日
|
||||
* @param string $comment
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
public function docComment($comment="\r\n")
|
||||
{
|
||||
$this->data['name'] = $name;
|
||||
$this->classBuild->setDocComment($comment);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -23,7 +33,7 @@ class Classes extends Iteration
|
||||
*/
|
||||
public function extend($extend)
|
||||
{
|
||||
$this->data['extend'] = $extend;
|
||||
$this->classBuild->extend($extend);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -33,9 +43,9 @@ class Classes extends Iteration
|
||||
* @param $interfaces
|
||||
* @return $this
|
||||
*/
|
||||
public function interfaces($interfaces)
|
||||
public function implement($interfaces)
|
||||
{
|
||||
$this->data['interfaces'] = $interfaces;
|
||||
$this->classBuild->implement($interfaces);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -44,9 +54,9 @@ class Classes extends Iteration
|
||||
* @time 2020年11月17日
|
||||
* @return $this
|
||||
*/
|
||||
public function isAbstract()
|
||||
public function abstract()
|
||||
{
|
||||
$this->data['type'] = 'Abstract';
|
||||
$this->classBuild->makeAbstract();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -55,21 +65,36 @@ class Classes extends Iteration
|
||||
* @time 2020年11月17日
|
||||
* @return $this
|
||||
*/
|
||||
public function isFinal()
|
||||
public function final()
|
||||
{
|
||||
$this->data['type'] = 'Final';
|
||||
$this->classBuild->makeFinal();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @time 2020年11月17日
|
||||
* @param $type
|
||||
* @param $param
|
||||
* @return void
|
||||
*/
|
||||
public function construct($type, $param)
|
||||
public function build()
|
||||
{
|
||||
$this->data['construct'][] = [$type, $param];
|
||||
return $this->classBuild;
|
||||
}
|
||||
|
||||
public function addMethod(Methods $method)
|
||||
{
|
||||
$this->classBuild->addStmt($method->build());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addProperty(Property $property)
|
||||
{
|
||||
$this->classBuild->addStmt($property->build());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTrait(Traits $trait)
|
||||
{
|
||||
$this->classBuild->addStmt($trait->build());
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@@ -1,55 +1,43 @@
|
||||
<?php
|
||||
namespace catcher\generate\classes;
|
||||
namespace catcher\generate\build\classes;
|
||||
|
||||
class Methods extends Iteration
|
||||
use catcher\generate\build\traits\CatchMethodReturn;
|
||||
use PhpParser\BuilderFactory;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
|
||||
class Methods
|
||||
{
|
||||
protected $method = [];
|
||||
|
||||
/**
|
||||
* set method name
|
||||
*
|
||||
* @time 2020年11月16日
|
||||
* @param string $method
|
||||
* @return $this
|
||||
*/
|
||||
public function name(string $method)
|
||||
use CatchMethodReturn;
|
||||
|
||||
protected $methodBuild;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->method['name'] = $method;
|
||||
$this->methodBuild = (new BuilderFactory())->method($name);
|
||||
}
|
||||
|
||||
public function public()
|
||||
{
|
||||
$this->methodBuild->makePublic();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* set visible
|
||||
*
|
||||
* @time 2020年11月16日
|
||||
* @param string $visibility
|
||||
* @return $this
|
||||
*/
|
||||
public function visible(string $visibility)
|
||||
public function protected()
|
||||
{
|
||||
$this->method['visible'] = $visibility;
|
||||
$this->methodBuild->makeProtected();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function makePublic()
|
||||
public function private()
|
||||
{
|
||||
$this->method['visible'] = 'public';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function makeProtected()
|
||||
{
|
||||
$this->method['visible'] = 'protected';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function makePrivate()
|
||||
{
|
||||
$this->method['visible'] = 'private';
|
||||
$this->methodBuild->makePrivate();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -65,25 +53,45 @@ class Methods extends Iteration
|
||||
*/
|
||||
public function param($param, $type = null, $default = null)
|
||||
{
|
||||
$this->method['params'][] = [
|
||||
'type' => $type,
|
||||
'param' => $param,
|
||||
'default' => $default,
|
||||
];
|
||||
$param = (new BuilderFactory())->param($param);
|
||||
|
||||
if ($type) {
|
||||
$param = $param->setType($type);
|
||||
}
|
||||
|
||||
if ($default) {
|
||||
$param = $param->setDefault($default);
|
||||
}
|
||||
|
||||
$this->methodBuild->addParam(
|
||||
$param
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回内容
|
||||
* 定义
|
||||
*
|
||||
* @time 2020年11月17日
|
||||
* @param $return
|
||||
* @time 2020年11月18日
|
||||
* @param $variable
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function return($return)
|
||||
public function declare($variable, $value)
|
||||
{
|
||||
$this->method['return'] = $return;
|
||||
$smt = new Expression(
|
||||
new Assign(
|
||||
new PropertyFetch(
|
||||
new Variable('this'),
|
||||
new Identifier($variable)
|
||||
),
|
||||
new Variable($value)
|
||||
)
|
||||
);
|
||||
|
||||
$this->methodBuild->addStmt($smt);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -91,12 +99,12 @@ class Methods extends Iteration
|
||||
* 返回值
|
||||
*
|
||||
* @time 2020年11月16日
|
||||
* @param $return
|
||||
* @param $returnType
|
||||
* @return $this
|
||||
*/
|
||||
public function returnType($return)
|
||||
public function returnType($returnType)
|
||||
{
|
||||
$this->method['return'] = $return;
|
||||
$this->methodBuild->setReturnType($returnType);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -109,9 +117,9 @@ class Methods extends Iteration
|
||||
* @param $comment
|
||||
* @return $this
|
||||
*/
|
||||
public function docComment($comment)
|
||||
public function docComment(string $comment)
|
||||
{
|
||||
$this->method['comment'] = $comment;
|
||||
$this->methodBuild->setDocComment($comment);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -124,7 +132,7 @@ class Methods extends Iteration
|
||||
*/
|
||||
public function toAbstract()
|
||||
{
|
||||
$this->method['type'] = 'Abstract';
|
||||
$this->methodBuild->makeAbstract();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -137,23 +145,14 @@ class Methods extends Iteration
|
||||
*/
|
||||
public function toFinal()
|
||||
{
|
||||
$this->method['type'] = 'Final';
|
||||
$this->methodBuild->makeFinal();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* join
|
||||
*
|
||||
* @time 2020年11月17日
|
||||
* @return $this
|
||||
*/
|
||||
public function join()
|
||||
|
||||
public function build()
|
||||
{
|
||||
$this->data[] = $this->method;
|
||||
|
||||
$this->method = [];
|
||||
|
||||
return $this;
|
||||
return $this->methodBuild;
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ namespace catcher\generate\build\classes;
|
||||
|
||||
use PhpParser\BuilderFactory;
|
||||
|
||||
class Properties
|
||||
class Property
|
||||
{
|
||||
protected $propertyBuild;
|
||||
|
||||
@@ -89,7 +89,7 @@ class Properties
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function build()
|
||||
{
|
||||
return $this->propertyBuild;
|
||||
|
@@ -1,37 +1,88 @@
|
||||
<?php
|
||||
namespace catcher\generate\classes;
|
||||
namespace catcher\generate\build\classes;
|
||||
|
||||
class Traits extends Iteration
|
||||
use PhpParser\BuilderFactory;
|
||||
|
||||
class Traits
|
||||
{
|
||||
protected $trait = [];
|
||||
protected $traitBuild;
|
||||
|
||||
public function name($name)
|
||||
protected $build;
|
||||
|
||||
public function use(...$names)
|
||||
{
|
||||
if (!empty($this->trait)) {
|
||||
$this->data[] = $this->trait;
|
||||
$this->build = new BuilderFactory;
|
||||
|
||||
$this->trait = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->trait['name'] = $name;
|
||||
$this->traitBuild = call_user_func_array([$this->build, 'useTrait'], $names);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function adaptation($name)
|
||||
public function and($name)
|
||||
{
|
||||
$this->trait['adaptation'] = $name;
|
||||
$this->traitBuild->and($name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* with
|
||||
*
|
||||
* @time 2020年11月19日
|
||||
* @param \Closure|null $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function with(\Closure $closure = null)
|
||||
{
|
||||
if ($closure instanceof \Closure) {
|
||||
$this->traitBuild->withe($closure($this));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @time 2020年11月19日
|
||||
* @param $name
|
||||
* @param null $method
|
||||
* @return $this
|
||||
*/
|
||||
public function adaptation($name, $method = null)
|
||||
{
|
||||
$this->build = $this->build->traitUseAdaptation($name. $method);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @time 2020年11月19日
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function as($name)
|
||||
{
|
||||
$this->build->as($name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @time 2020年11月19日
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function insteadof($name)
|
||||
{
|
||||
$this->trait['insteadof'] = $name;
|
||||
$this->build->insteadof($name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function as($as)
|
||||
public function build()
|
||||
{
|
||||
$this->trait['as'] = $as;
|
||||
return $this->traitBuild;
|
||||
}
|
||||
}
|
||||
|
@@ -1,23 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace catcher\generate\classes;
|
||||
namespace catcher\generate\build\classes;
|
||||
|
||||
use think\helper\Str;
|
||||
use PhpParser\BuilderFactory;
|
||||
|
||||
class Uses extends Iteration
|
||||
class Uses
|
||||
{
|
||||
protected $uses;
|
||||
|
||||
public function __construct($uses)
|
||||
public function name(string $name, string $as = '')
|
||||
{
|
||||
$delimiter = ' as ';
|
||||
$build = (new BuilderFactory())->use($name);
|
||||
|
||||
foreach ($uses as $key => $use) {
|
||||
if (Str::contains($use, $delimiter)) {
|
||||
$uses[$key] = explode($delimiter, $use);
|
||||
}
|
||||
if ($as) {
|
||||
$build->as($as);
|
||||
}
|
||||
|
||||
$this->data = $uses;
|
||||
return $build;
|
||||
}
|
||||
|
||||
public function function(string $function)
|
||||
{
|
||||
return (new BuilderFactory())->useFunction($function);
|
||||
}
|
||||
|
||||
public function const(string $const)
|
||||
{
|
||||
return (new BuilderFactory())->useConst($const);
|
||||
}
|
||||
}
|
@@ -2,30 +2,129 @@
|
||||
namespace catcher\generate\build\traits;
|
||||
|
||||
|
||||
class MethodReturn
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
|
||||
trait CatchMethodReturn
|
||||
{
|
||||
public function index()
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @time 2020年11月18日
|
||||
* @param $model
|
||||
* @return $this
|
||||
*/
|
||||
public function index($model)
|
||||
{
|
||||
$class = new Name('CatchResponse');
|
||||
|
||||
$arg = new Arg(new MethodCall(
|
||||
new PropertyFetch(
|
||||
new Variable('this'), new Identifier($model)
|
||||
),
|
||||
new Identifier('getList')
|
||||
));
|
||||
|
||||
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'paginate', [$arg])));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function save()
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @time 2020年11月18日
|
||||
* @param $model
|
||||
* @return $this
|
||||
*/
|
||||
public function save($model)
|
||||
{
|
||||
$arg = new Arg(new MethodCall(
|
||||
new PropertyFetch(
|
||||
new Variable('this'), new Identifier($model)
|
||||
),
|
||||
new Identifier('storeBy'), [new Arg(new MethodCall(new Variable('request'), new Identifier('post')))]
|
||||
));
|
||||
|
||||
$class = new Name('CatchResponse');
|
||||
|
||||
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function update()
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @time 2020年11月18日
|
||||
* @param $model
|
||||
* @return $this
|
||||
*/
|
||||
public function update($model)
|
||||
{
|
||||
$arg = new Arg(new MethodCall(
|
||||
new PropertyFetch(
|
||||
new Variable('this'), new Identifier($model)
|
||||
),
|
||||
new Identifier('updateBy'), [
|
||||
new Arg(new Variable('id')),
|
||||
new Arg(new MethodCall(new Variable('request'), new Identifier('post')))
|
||||
]
|
||||
));
|
||||
|
||||
$class = new Name('CatchResponse');
|
||||
|
||||
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function read()
|
||||
public function read($model)
|
||||
{
|
||||
$arg = new Arg(new MethodCall(
|
||||
new PropertyFetch(
|
||||
new Variable('this'), new Identifier($model)
|
||||
),
|
||||
new Identifier('findBy'), [
|
||||
new Arg(new Variable('id'))
|
||||
]
|
||||
));
|
||||
|
||||
$class = new Name('CatchResponse');
|
||||
|
||||
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @time 2020年11月18日
|
||||
* @param $model
|
||||
* @return $this
|
||||
*/
|
||||
public function delete($model)
|
||||
{
|
||||
$arg = new Arg(new MethodCall(
|
||||
new PropertyFetch(
|
||||
new Variable('this'), new Identifier($model)
|
||||
),
|
||||
new Identifier('deleteBy'), [
|
||||
new Arg(new Variable('id'))
|
||||
]
|
||||
));
|
||||
|
||||
$class = new Name('CatchResponse');
|
||||
|
||||
$this->methodBuild->addStmt(new Return_(new StaticCall($class, 'success', [$arg])));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,20 +1,28 @@
|
||||
<?php
|
||||
namespace catcher\generate\build\types;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
|
||||
class Array_
|
||||
class Arr
|
||||
{
|
||||
public function build($array)
|
||||
public function build($fields)
|
||||
{
|
||||
$items = [];
|
||||
|
||||
foreach ($array as $item) {
|
||||
$items[] = new ArrayItem(new String_($item));
|
||||
foreach ($fields as $field) {
|
||||
$arrItem = new ArrayItem(new String_($field['name']));
|
||||
if ($field['comment']) {
|
||||
$arrItem->setDocComment(
|
||||
new Doc('// ' . $field['comment'])
|
||||
);
|
||||
}
|
||||
$items[] = $arrItem;
|
||||
|
||||
}
|
||||
|
||||
return new \PhpParser\Node\Expr\Array_($items);
|
||||
return new Array_($items);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user