Ctags: PHP heredoc (<<

Criado em 20 nov. 2020  ·  8Comentários  ·  Fonte: universal-ctags/ctags

RESUMO:

A geração de tags para quando a sintaxe PHP heredoc ( <<< ) é encontrada em um arquivo. Como a sintaxe nowdoc PHP é basicamente a mesma, esse é outro elemento da linguagem que interrompe a análise do arquivo.

O nome do analisador:

não tenho certeza sobre isso. Supondo PHP

A linha de comando que você usou para executar ctags:
$ ctags --options=NONE foo.php
O conteúdo do arquivo de entrada:
<?php

class LivingBeings {

    public function doSomething()
    {
        $foo = <<<FOO
        FOO;
    }

    public function doSomethingElse()
    {
    }
}
A saída das tags com a qual você não está satisfeito:

O método doSomethingElse não está listado no arquivo. Assim que eu comentar a parte heredoc , o método é indexado normalmente, como você pode ver na seção "saída esperada" adiante.

!_TAG_FILE_FORMAT   2   /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED   1   /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_OUTPUT_EXCMD  mixed   /number, pattern, mixed, or combine/
!_TAG_OUTPUT_FILESEP    slash   /slash or backslash/
!_TAG_OUTPUT_MODE   u-ctags /u-ctags or e-ctags/
!_TAG_PATTERN_LENGTH_LIMIT  96  /0 for no limit/
!_TAG_PROC_CWD  /tmp/   //
!_TAG_PROGRAM_AUTHOR    Universal Ctags Team    //
!_TAG_PROGRAM_NAME  Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL   https://ctags.io/   /official site/
!_TAG_PROGRAM_VERSION   5.9.0   /5a136315/
LivingBeings    foo.php /^class LivingBeings {$/;"  c
doSomething foo.php /^    public function doSomething()$/;" f   class:LivingBeings
A saída de tags que você espera:
!_TAG_FILE_FORMAT   2   /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED   1   /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_OUTPUT_EXCMD  mixed   /number, pattern, mixed, or combine/
!_TAG_OUTPUT_FILESEP    slash   /slash or backslash/
!_TAG_OUTPUT_MODE   u-ctags /u-ctags or e-ctags/
!_TAG_PATTERN_LENGTH_LIMIT  96  /0 for no limit/
!_TAG_PROC_CWD  /tmp/   //
!_TAG_PROGRAM_AUTHOR    Universal Ctags Team    //
!_TAG_PROGRAM_NAME  Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL   https://ctags.io/   /official site/
!_TAG_PROGRAM_VERSION   5.9.0   /5a136315/
LivingBeings    foo.php /^class LivingBeings {$/;"  c
doSomething foo.php /^    public function doSomething()$/;" f   class:LivingBeings
doSomethingElse foo.php /^    public function doSomethingElse()$/;" f   class:LivingBeings
A versão das ctags:
$ ctags --version
Universal Ctags 5.9.0(5a136315), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Nov 20 2020, 11:46:20
  URL: https://ctags.io/
  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +yaml, +packcc
Como você obtém o binário ctags:

Construindo localmente:

$ cd ctags_source
$ make clean && make distclean
$ ./autogen.sh
$ ./configure --prefix=$HOME
$ make
$ make install
Parser buenhancement

Todos 8 comentários

@jespinal , você está falando sobre essa mudança: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes ?

$ git diff |cat
git diff |cat
diff --git a/parsers/php.c b/parsers/php.c
index e3fdc241..ace25561 100644
--- a/parsers/php.c
+++ b/parsers/php.c
@@ -682,6 +682,8 @@ static void parseHeredoc (vString *const string)
            int extra = EOF;

            c = getcFromInputFile ();
+           if (c == ' ' || c == '\t')
+               c = getcFromInputFile ();
            for (len = 0; c != 0 && (c - delimiter[len]) == 0; len++)
                c = getcFromInputFile ();

$ cat input.php
cat input.php
<?php
// Taken from https://github.com/universal-ctags/ctags/issues/2717
// submitted by <strong i="5">@jespinal</strong>
class LivingBeings {

    public function doSomething()
    {
        $foo = <<<FOO
        FOO;
    }

    public function doSomethingElse()
    {
    }
}
$ u-ctags -o - input.php
u-ctags -o - input.php
LivingBeings    input.php   /^class LivingBeings {$/;"  c
doSomething input.php   /^    public function doSomething()$/;" f   class:LivingBeings
$

@masatake isso não é suficiente, porque o marcador de finalização costumava estar em sua própria linha , enquanto a nova versão remove essa restrição. Não acho a explicação muito clara:

A implementação que estou propondo evita esse problema verificando se existe uma continuação do marcador encontrado e, em caso afirmativo, se forma um identificador válido.

mas eu diria que isso significa que, a menos que haja um caractere identificador após a linha prefixada com o marcador de terminação, é de fato um marcador de terminação. Então END; é uma rescisão (dado que o marcador é END ), mas ENDFOO não é.

BTW, como esta é uma alteração sintática incompatível com versões anteriores, não sei o que queremos fazer sobre isso. Mas eu acho que se o PHP está feliz em quebrá-lo, nós também podemos, especialmente porque é bastante improvável que cause problemas. Idealmente, acho que usaríamos a sintaxe atual para *.php[1-6] e a nova para o resto, mas isso pode ser muito problemático para o que vale a pena.

@jespinal , você está falando sobre essa mudança: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes ?

Desculpe, @masatake , por algum motivo não fui notificado de sua pergunta.

Sim, estou falando sobre essa mudança. Mas isso foi implementado no PHP 7.3 (a versão estável atual é 7.4, e a versão 8 está disponível). Não sei por que isso não foi relatado antes, considerando a vasta base de usuários de ctags e PHP.

Estou adicionando algumas capturas de tela de trechos de código derivados do exemplo anterior para (espero) lançar alguma luz sobre o que eles consideram sintaxe válida / inválida em relação à nova sintaxe heredoc / nowdoc (o RFC não é claro o suficiente, eu pensar).

Neste exemplo, ' TEXT ' (o segundo) é o marcador final. Portanto, o terceiro ' TEXT; é uma string sintaticamente inválida na visualização do analisador, pois seria esperado apenas um ponto e vírgula ou vírgula:

test-001-2020-11-24 22-33-30

Um caso semelhante ao anterior:
test-003-2020-11-24 22-37-04

Se fosse um ponto-e-vírgula ou vírgula, o analisador de php teria ficado feliz. Por exemplo

        echo <<<TEXT
            some string 
        TEXT, 'some other string';

Aos olhos do analisador, isso é o mesmo que:

    echo 'some string', 'some other string';

O seguinte é um exemplo válido, pois o analisador sabe que ' TEXT ' e ' TEXTUAL ' são duas strings diferentes:

test-002-2020-11-24 22-36-25

Aqui estão alguns snippets inválidos devido ao recuo incorreto. Especificamente, para a instrução RFC: "Se o marcador de fechamento for indentado além de qualquer linha do corpo, um ParseError será lançado:"

test-004-2020-11-24 22-38-11

test-005-2020-11-24 22-39-38

@jespinal obrigado, mas se você tiver um texto normativo isso será ainda melhor :) É sempre difícil adivinhar a lógica com base apenas em alguns casos, ao passo que se tivermos o texto normativo podemos apenas implementá-lo e espero que funcione. E, na verdade, acho que temos o suficiente com o link de @masatake e suas informações: +1:

@masatake Eu não prometo nada dado o pouco tempo que tenho encontrado ultimamente, mas vou tentar dar uma olhada nisso logo, a menos que você chegue antes de mim :)

BTW @jespinal, se ninguém reclamou, eu realmente acho que é porque há muito pouco uso dessa sintaxe e oferecemos suporte à sintaxe pré-7.3, então os únicos casos em que se veria um problema é com o uso de sintaxe 7.3+, o que implica o uso de neredoc / nowdoc em primeiro lugar :)

Você ficou inativo por um tempo. Então, eu não esperava receber um comentário seu.
Mas, agora recebemos o sinal "auto-atribuído" de você. @ b4n , obrigado pela oferta.

@masatake, você foi sábio em não esperar muito de mim, já que eu realmente não encontrei tempo para muitas contribuições UCtags / Geany ultimamente: decepcionado:. Estou tentando descobrir como alocar tempo aqui novamente, então espero ser mais ativo novamente, mas não posso prometer ainda.

No entanto, consulte # 2734 para uma solução para o problema em questão :)

Obrigada!

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

Questões relacionadas

fabiensabatie picture fabiensabatie  ·  3Comentários

cweagans picture cweagans  ·  13Comentários

blackb1rd picture blackb1rd  ·  8Comentários

cweagans picture cweagans  ·  4Comentários

softinio picture softinio  ·  6Comentários