wata727/phan-query-plugin

一个Phan插件,无需编写插件即可添加新规则

0.1.0 2018-05-05 13:10 UTC

This package is auto-updated.

Last update: 2024-09-15 01:35:30 UTC


README

Build Status Latest Stable Version MIT License

一个无需编写插件即可添加新规则的Phan插件。本插件灵感来源于Querly

安装

您可以使用composer安装此插件。

$ composer require --dev wata727/phan-query-plugin

之后,将此插件路径设置为.phan/config.php

<?php

return [
    "plugins" => [__DIR__."/../vendor/wata727/phan-query-plugin/plugins/QueryPlugin.php"]
];

快速入门

首先,创建以下文件

.phan/config.php:

<?php

return [
    "plugins" => [__DIR__."/../vendor/wata727/phan-query-plugin/plugins/QueryPlugin.php"]
];

.phan/query.php:

<?php

return [
    [
        "type" => "PhanQueryCatFound",
        "message" => "Cat Found",
        "pattern" => '$cat->meow();',
    ]
];

test.php:

<?php

namespace Foo\Bar;

class Cat
{
    public function meow()
    {
        echo "Meow!";
    }
}

$cat = new Cat();
$cat->meow();

尝试以下命令

$ vendor/bin/phan test.php

您可以得到结果

test.php:12 PhanQueryCatFound Cat Found

发生了什么?

此插件加载.phan/query.php并搜索与Query定义的pattern匹配的代码。在上面的例子中,由于匹配$cat->meow();的代码存在于第12行,因此它被作为Phan的问题发出。

发出的问题具有类型和消息,以及Phan原始问题的类型。这些是您在Query中定义的typemessage

与正则表达式有什么区别?

此插件使用AST进行节点匹配。例如,$cat->meow($arg1, $arg2);与以下所有内容匹配

  • $cat->meow($arg1, $arg2);
  • $cat->meow($arg1 , $arg2);
  • $cat->meow($arg1,$arg2);

查询语法

可以在pattern中写什么类型的语法?这是类似于PHP的模式匹配语法,满足以下条件

  • 模式表达式必须是有效的PHP
    • 例如,需要尾部分号。
  • 但在模式中可以使用<Klass>语法。

<Klass> 语法

您可以在Query的模式中使用<Klass>语法。如果您使用它,以下模式与上面的test.php匹配。

<?php

return [
    [
        "type" => "PhanQueryAllCatFound",
        "message" => "Cat Found",
        "pattern" => '<Foo\Bar\Cat>->meow();',
    ]
];

这意味着当使用此模式时,Query检查变量的类型。另外,如果您指定了<any>,则它匹配所有变量。

测试您的查询

您可以编写一个测试来确保Query正确工作。例如

<?php

return [
    [
        "type" => "PhanQueryCatFound",
        "message" => "Cat Found",
        "pattern" => '$cat->meow();',
        "test" => [
            "match" => <<<'EOD'
<?php

namespace Foo\Bar;

class Cat
{
    public function meow()
    {
        echo "Meow!";
    }
}

$cat = new Cat();
$cat->meow();
EOD
            ,
            "unmatch" => <<<'EOD'
<?php

namespace Foo\Bar;

class Cat
{
    public function meow()
    {
        echo "Meow!";
    }
}

$dog = new Cat();
$dog->meow();
EOD
        ],
    ],
];

match值是匹配pattern的代码,而unmatch值是不匹配pattern的代码。您可以使用以下命令运行测试

$ vendor/bin/phan_query_test
All 2 tests are passed!

作者

渡边和马