Ctags: 功能请求:带有(具有)的 Perl 属性

创建于 2019-03-31  ·  14评论  ·  资料来源: universal-ctags/ctags

目前 Perl 扩展了 Moose、Mouse、Moo 和 Mo 等。 这些模块都有一个共同点——它们的属性选择器是用has 。 我相信我们可以假设任何遵循 Moose 建立的惯例的东西,

has $name|@$names => %options是众多对象构建系统之一的正确格式属性。

我们必须涵盖诸如

has "foo" => ()
has ("foo" => ())
has [qw/foo bar/] => ()
has ([qw/foo bar/] => ())
Parser buenhancement

所有14条评论

@dtikhonov ,你能看看这个吗?

穆斯等人。 只是模块,而has是一个函数调用,而不是 Perl 关键字。 在 ctags Perl 解析器中包含对 Moose 的支持会使我们陷入困境,因为有许多 Perl 模块引入了看起来像关键字的函数调用。

……我对这个话题很感兴趣。 过去 3 年,我改进了 ctags 来处理 DSL。

有关我的愿景,请参阅http://docs.ctags.io/en/latest/running-multi-parsers.html?highlight=subparser#tagging -definitions-of-higher-upper-level-language-sub-base。

Moose 子解析器可以在 Perl 解析器上运行。


package Point;
use Moose; # automatically turns on strict and warnings

has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');

sub clear {
    my $self = shift;
    $self->x(0);
    $self->y(0);
}

package Point3D;
use Moose;

extends 'Point';

has 'z' => (is => 'rw', isa => 'Int');

after 'clear' => sub {
    my $self = shift;
    $self->z(0);
};

当 Perl 解析器发现关键字“use”时,Perl 解析器会将它通知给注册的子解析器。
Moose 子解析器就是这样的子解析器。
如果通知的模块名称是“Moose”,Moose 子解析器会自行激活。
Moose 子解析器扫描名为 cork 的 ctags 内部符号表以查找 Perl 语言对象
Perl 解析器标记为“包”类型。 Moose 子解析器可能会在符号表中找到“Point”。
它已经被 Perl 解析器标记了。 然而,Moose 解析器使用“类”类的“Moose”语言为“Point”创建了一个新标签。

Moose 子解析器将“点”推送到范围堆栈。
Moose 子解析器发现“has”作为关键字。 Moose 子解析器为“x”创建一个标记,作为“has”的下一个标记。 为“x”制作标签,“ scope:class :Point language:Moose ”附加到“x”...

关于C++解析器,我已经实现了这个想法。
QtMoc 子解析器用于使用 Qt 解析 C++ 代码。 QtMoc 子解析器识别信号和槽,它们是作为 C++ 语言的一种方言引入的。

要实现子解析器,我必须从其基本解析器的维护者那里获得许可。
我猜@dtikhonov不是那么积极,因为引入子解析器会使基本解析器的代码变得复杂。

如果解析器维护者和我有冲突,我想在解析器中引入子解析器,我会退出实现子解析器,因为拥有解析器维护者是 u-ctags 项目中最重要的事情。

@dtikhonov ,如果您对将 Moose 实现为子解析器的想法感兴趣,请告诉我。
我将制作一个原型来展示对 Perl 解析器源代码的影响。

感谢您的阅读。

我意识到这是一个功能,在引擎盖下。 但是,这是一个实现细节。 同样,当您以面向对象的方式编程时,包是“类”,而“子”是方法。 当您使用面向对象的 perl 时,所有这些命名法都会发生变化,但在每种情况下,您都可以使用非 OO 术语。 在上述所有情况下,虽然在推断用户为哪个范式编写代码时增加了复杂性。 也就是说,“有”缺乏这些复杂性。 如果你看到它,你有两种可能的解释 (a) 你正在调用一个函数“has”,在这种情况下,期望的行为是不做任何事情,就像我们现在所做的那样; 或者,(b) 您使用的是 Moose-esque 属性声明。

您回复中的“Moose et al”引用显示了 Perl 中使用这些模块构建器框架(包含has -attribute 声明)的约定有多强。 Moose 很容易成为 Perl 最流行的模块之一(它在 metacpan 上的星数比 DBI 和 LWP 多)。

我不是说我们不能有任何误报,但我不知道是谁发布了不遵循这个惯例模块任何人及其代表,帮助了很多人。 此外,我真的怀疑这个 ctags 在理论上是合理的,而不仅仅是实用的。

@masatake 子解析器的想法听起来比我的实现更好、更完整,而且 perl 实际上已经通过测试use并在内部为其中一些模块调用不同的语义做了类似的事情。

https://github.com/universal-ctags/ctags/blob/master/parsers/perl.c#L348

我想问题在于您必须枚举触发 Moose-parser 的模块列表,这不会太糟糕。 您还必须假设没有人在运行 Moose 的子类,这很棘手,但如果他们这样做,更糟糕的情况是他们会丢失 Moose-subparser。 而且,我对此表示同意——它不会比他们拥有的更糟糕。

如果您需要帮助为 Moose 编写 C 解析器,我也可以提供帮助。

我几乎认为这种用于 Perl 和 Moose 的静态解析器在 ctags 之外也很有用。 目前解析 perl 是不安全的,并且没有任何保证。 例如,这将允许其他项目在 Perl 上安全地运行测试覆盖率。

@masatake ,Perl 5 是一个缓慢移动的目标,没有太多需要维护的,所以我作为perl.c维护者的工作很容易。 我浏览了您引用的子解析器文档——我只能说:哇! 坦率地说,我没有密切关注 Universal Ctags 的发展,我看到你已经取得了很大的进步。

@EvanCarroll ,代码对话:随意尝试一下。 我也没有嫁给perl.c 。 它的部分内容非常丑陋,事后看来,有些事情应该以不同的方式实施。 关于“用”的用法:触及,点取。

酷,酷。 我会看看这个周末我能完成什么。 我也会检查子解析器框架的工作。

一个原型工作。
@EvanCarroll ,你可以从#2070 开始。

我专注于 TypeScript 解析器。 所以我暂时不会在#2070 上工作。
随心所欲地破解。

[yamato@slave]~/var/ctags/perl-moose/Units/simple-moose.d% cat input.pl
cat input.pl
# Taken from https://metacpan.org/pod/Moose
package Point;
use Moose; # automatically turns on strict and warnings

has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');

sub clear {
    my $self = shift;
    $self->x(0);
    $self->y(0);
}

package Point3D;
use Moose;

extends 'Point';

has 'z' => (is => 'rw', isa => 'Int');

after 'clear' => sub {
    my $self = shift;
    $self->z(0);
};

no Moose;
package Line;

[yamato@slave]~/var/ctags/perl-moose/Units/simple-moose.d%  ./ctags --fields=+lineK --sort=no -o - --extras=+s ./input.pl
 ./ctags --fields=+lineK --sort=no -o - --extras=+s ./input.pl
zsh: no such file or directory: ./ctags
[yamato@slave]~/var/ctags/perl-moose/Units/simple-moose.d% ../../ctags --fields=+lineK --sort=no -o - --extras=+s ./input.pl
../../ctags --fields=+lineK --sort=no -o - --extras=+s ./input.pl
Point   ./input.pl  /^package Point;$/;"    package line:2  language:Perl
Point   ./input.pl  /^package Point;$/;"    class   line:2  language:Moose
x   ./input.pl  /^has 'x' => (is => 'rw', isa => 'Int');$/;"    attribute   line:5  language:Moose  class:Point
y   ./input.pl  /^has 'y' => (is => 'rw', isa => 'Int');$/;"    attribute   line:6  language:Moose  class:Point
clear   ./input.pl  /^sub clear {$/;"   subroutine  line:8  language:Perl
clear   ./input.pl  /^sub clear {$/;"   method  line:8  language:Moose  class:Point
Point3D ./input.pl  /^package Point3D;$/;"  package line:14 language:Perl
Point3D ./input.pl  /^package Point3D;$/;"  class   line:14 language:Moose  inherits:Point  end:26
z   ./input.pl  /^has 'z' => (is => 'rw', isa => 'Int');$/;"    attribute   line:19 language:Moose  class:Point3D
clear   ./input.pl  /^after 'clear' => sub {$/;"    attribute   line:21 language:Moose  class:Point3D
Line    ./input.pl  /^package Line;$/;" package line:27 language:Perl
[yamato@slave]~/var/ctags/perl-moose/Units/simple-moose.d% ./ctags --list-subparsers
./ctags --list-subparsers
zsh: no such file or directory: ./ctags
[yamato@slave]~/var/ctags/perl-moose/Units/simple-moose.d% ../../ctags --list-subparsers
../../ctags --list-subparsers
#NAME                BASEPARSER        DIRECTIONS
AnsiblePlaybook      Yaml              base <> sub {bidirectional}
Autoconf             M4                base <> sub {bidirectional}
Automake             Make              base <= sub {dedicated}
ITcl                 Tcl               base <> sub {bidirectional}
JAXRS                Java              base => sub {shared}
LinuxKernel          C                 base => sub {shared}
LinuxOVS             C                 base => sub {shared}
Moose                Perl              base <> sub {bidirectional}
OpenVSwitch          C                 base => sub {shared}
PythonLoggingConfig  Iniconf           base <> sub {bidirectional}
PythonMain           Python            base => sub {shared}
PythonTuned          Python            base => sub {shared}
QtMoc                C++               base <> sub {bidirectional}
RSpec                Ruby              base => sub {shared}
SystemdUnit          Iniconf           base <= sub {dedicated}
TclOO                Tcl               base <> sub {bidirectional}
YumRepo              Iniconf           base <= sub {dedicated}
selinuxPolicy        selinuxPolicyBase base => sub {shared}
servlet              Java              base => sub {shared}
[yamato@slave]~/var/ctags/perl-moose% ./ctags --list-kinds-full=Moose   
#LETTER NAME      ENABLED REFONLY NROLES MASTER DESCRIPTION
a       attribute yes     no      0      NONE   attributes
c       class     yes     no      0      NONE   classes
m       method    yes     no      0      NONE   methods

一个原型工作。 @EvanCarroll ,你可以从#2070 开始。

那太快了! 👍

@masatake令人印象深刻。 还有工作要做吗? 我看到你已经实现了findAttribute和语言回调参考?

@masatake令人印象深刻。 还有工作要做吗?

这就是我想知道的:-)。
如果我错过了你想要的东西,请告诉我。
我只阅读了 Moose 文档的几个部分。

@masatake很酷,我用 github 查看了补丁。 如果你不能解决它,我这个周末去看看。 =) 但是您可能会在 0.0001 秒内完成。

但您可能会在 0.0001 秒内完成。

这不是真的。

为了改进解析器,我们需要 4 件事:关于 ctags 内部 API 的知识,关于目标语言的知识,Moose,时间和激情:-P。

我对麋鹿一无所知。 这是最重要的。
例如,当前的解析器不捕获附加到带有with的类的规则,并用“use Moose::Rule”定义。 我所知道的只是“规则”。 但是,您可能知道 ctags 应该捕获的项目更多。

难道你不希望 ctags 捕捉到这样的规则吗?
如果规则附加到一个类,我认为该类的标签应该有一个名为“规则:“ 场地。

需要知道目标语言的人的这些请求来发展这个项目。

我可以实施其中的一些。 你可以实现其他的。 如果有这样的要求,我们可以稍后实施。

我们可以扩展当前的实现以支持 Mouse、Moo 和 Mo。我们可以为您做任何事情
想要不修改原始 Perl 解析器。

抱歉,我发现你已经在#2070 中给了我重要的评论。 谢谢你。

此页面是否有帮助?
0 / 5 - 0 等级