Ctags: Solicitação de recurso: atributos Perl com (tem)

Criado em 31 mar. 2019  ·  14Comentários  ·  Fonte: universal-ctags/ctags

Atualmente, o Perl é estendido com Moose, Mouse, Moo e Mo e semelhantes. Todos esses módulos têm uma semelhança - seus seletores de atributo são estabelecidos com has . Acredito que podemos supor que tudo o que segue a convenção estabelecida por Moose de,

has $name|@$names => %options é um atributo formado corretamente para um dos muitos sistemas de construção de objetos que existem.

Teríamos que cobrir coisas como

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

Todos 14 comentários

@dtikhonov , você poderia olhar para isso?

Moose et al. são apenas módulos e has é uma chamada de função, não uma palavra-chave Perl. Incluir suporte para Moose no analisador ctags Perl nos colocaria em uma ladeira escorregadia, pois há muitos módulos Perl que introduzem chamadas de função que parecem palavras-chave.

... Estou muito interessado neste tópico. Nos últimos 3 anos, melhorei ctags para lidar com DSLs.

Consulte http://docs.ctags.io/en/latest/running-multi-parsers.html?highlight=subparser#tagging -definitions-of-mais-alto-nível-superior-sub-base de linguagem sobre minha visão.

O subparser Moose pode ser executado no parser 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);
};

Quando o analisador Perl encontra uma palavra-chave "usar", o analisador Perl a notifica aos subparsers registrados.
Moose subparser é um subparser.
O subparser Moose se ativa se o nome do módulo notificado for "Moose".
O subparser Moose examina a tabela de símbolos internos de ctags chamada cork para encontrar um objeto de linguagem Perl
marcado como "pacote" pelo analisador Perl. O subparser Moose pode encontrar "Point" na tabela de símbolos.
Já está marcado pelo analisador Perl. No entanto, o analisador Moose cria uma nova tag para "Point" com "classe", uma espécie de linguagem "Moose".

O subparser Moose empurra o "Ponto" para a pilha de escopo.
O subparser Moose encontra "has" como uma palavra-chave. O subparser Moose cria uma tag para "x" encontrada como o próximo token para "tem". A criação da tag para "x", " scope: class : Point language: Moose " é anexada a "x" ...

Sobre o analisador C ++, já implementei essa ideia.
O subparser QtMoc é para analisar código C ++ usando Qt. O subparser QtMoc reconhece o sinal e o slot, que são introduzidos como um dialeto da linguagem C ++.

Para implementar um sub-analisador, preciso obter permissão do mantenedor de seu analisador base.
Eu acho que @dtikhonov não é tão positivo porque a introdução de um subparser torna o código do parser de base complicado.

Se houver conflito entre um mantenedor do parser e eu, que deseja introduzir um subparser ao parser, desistirei de implementar o subparser porque ter um mantenedor do parser é a coisa mais importante no projeto u-ctags.

@dtikhonov , se você estiver interessado na ideia de implementar o Moose como um subparser, me avise.
Vou fazer um protótipo para mostrar o impacto no código-fonte do analisador Perl.

Obrigado por ler.

Eu percebo que é uma função, por baixo do capô. Mas, isso é um detalhe de implementação. No mesmo sentido, pacotes são "classes" quando você está programando de maneira orientada a objetos, e "subs" são métodos. Toda essa nomenclatura muda quando você usa perl Orientado a Objetos, mas em cada caso você pode fazer uso da terminologia não OO. Em todos os casos acima, porém, há complexidades adicionais em inferir para qual paradigma o usuário escreveu o código. Dito isso, "tem" carece dessas complexidades. Se você o vir, terá duas interpretações possíveis (a) você está chamando uma função "tem", caso em que o comportamento desejado seria não fazer nada, como fazemos agora; ou (b) você está usando uma declaração de atributo no estilo Moose.

A citação "Moose et al" de sua resposta mostra o quão forte é essa convenção em Perl para usar essas estruturas construtoras de módulo (que abrangem a declaração has -atributo). Moose é facilmente um dos módulos mais populares para Perl (tem mais estrelas no metacpan do que DBI e LWP).

Não estou dizendo que não poderíamos ter nenhum falso-positivo, mas não conheço ninguém que publicou um módulo que não segue esta convenção e que ajudará muita gente. Além disso, eu realmente duvido que esse ctags seja teoricamente correto, e não apenas prático.

@masatake a ideia do subparser soa melhor e mais completa do que minha implementação, e perl na verdade já faz algo semelhante testando use e invocando semânticas diferentes para alguns desses módulos internamente.

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

Acho que o problema é que você teria que enumerar a lista de módulos que acionam o analisador Moose, o que não seria tão ruim. Você também teria que assumir que ninguém está executando uma subclasse de Moose, o que é complicado, mas se eles estivessem fazendo isso, o pior cenário seria perderiam o subparser Moose. E, estou bem com isso - não seria pior do que o que eles têm.

Se você quiser ajuda para escrever um analisador C para Moose, eu posso ajudar com isso também.

Estou quase convencido de que esse tipo de analisador estático para Perl e Moose também seria útil fora dos ctags. Atualmente, a análise de perl não é segura e não há garantias. Isso permitiria que outros projetos executassem com segurança a cobertura de teste no Perl, por exemplo.

@masatake , Perl 5 é um alvo tão lento que não há muito o que manter, então meu trabalho como mantenedor de perl.c tem sido fácil. Eu examinei a documentação do subparser que você referiu - tudo o que posso dizer é: uau! Para ser franco, não tenho acompanhado o desenvolvimento do Universal Ctags de perto e vejo que você fez grandes avanços.

@EvanCarroll , código fala: sinta-se à vontade para tentar. Também não sou casado com perl.c . Algumas partes são francamente feias e, em retrospectiva, algumas coisas deveriam ter sido implementadas de forma diferente. No que diz respeito ao uso de "usar": touche, ponto tomado.

Legal legal. Vou ver o que posso fazer neste fim de semana então. Vou verificar o trabalho na estrutura do subparser também.

Um protótipo funciona.
@EvanCarroll , você pode começar do # 2070.

Estou me concentrando no analisador TypeScript. Portanto, não vou trabalhar no # 2070 por um tempo.
Hack como quiser.

[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

Um protótipo funciona. @EvanCarroll , você pode começar do # 2070.

Isso foi rápido! 👍

@masatake impressionante. Há mais trabalho a fazer? Vejo que você implementou findAttribute e a referência de retorno de chamada do idioma?

@masatake impressionante. Há mais trabalho a fazer?

É isso que gostaria de saber :-).
Se eu perdi o que você queria, por favor, me avise.
Eu li apenas algumas partes do documento de Moose.

@masatake bom negócio, eu revisei o patch com o github. Se você não puder fazer isso, vou dar uma olhada neste fim de semana. =) Mas você provavelmente terá feito em 0,0001 segundos.

Mas você provavelmente terá feito isso em 0,0001 segundos.

Não é verdade.

Para melhorar o analisador, precisamos de 4 coisas: conhecimento sobre a API interna ctags, conhecimento sobre a linguagem alvo, Moose, tempo e paixão :-P.

Não tenho conhecimento sobre Moose. Este é o mais importante.
por exemplo, o analisador atual não captura uma regra anexada a uma classe com with e definida com "use Moose :: Rule". O que eu sei é apenas "regra". No entanto, você pode saber mais itens que as ctags devem capturar.

Você não espera que as ctags capturem essas regras?
Se uma regra for anexada a uma classe, acho que a tag da classe deve ter um campo chamado "regra:" campo.

Essas solicitações de uma pessoa que conhece o idioma de destino são necessárias para desenvolver este projeto.

Posso implementar alguns deles. Você pode implementar outros. Podemos implementar mais tarde se essas solicitações forem.

Podemos estender a implementação atual para oferecer suporte a Mouse, Moo e Mo. Podemos fazer qualquer coisa que você
deseja SEM modificar o analisador Perl original.

Desculpe, descobri que você já me fez comentários importantes em # 2070. Obrigada.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

sparkcanon picture sparkcanon  ·  3Comentários

alphaCTzo7G picture alphaCTzo7G  ·  7Comentários

jespinal picture jespinal  ·  8Comentários

fommil picture fommil  ·  19Comentários

lvc picture lvc  ·  3Comentários