Ctags: PHP heredoc (<<

Créé le 20 nov. 2020  ·  8Commentaires  ·  Source: universal-ctags/ctags

RÉSUMÉ:

La génération des balises s'arrête lorsque la syntaxe PHP heredoc ( <<< ) est rencontrée dans un fichier. Comme la syntaxe PHP nowdoc est fondamentalement la même, c'est un autre élément de langage qui casse l'analyse du fichier.

Le nom de l'analyseur :

pas sûr à ce sujet. En supposant que PHP

La ligne de commande que vous avez utilisée pour exécuter ctags :
$ ctags --options=NONE foo.php
Le contenu du fichier d'entrée :
<?php

class LivingBeings {

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

    public function doSomethingElse()
    {
    }
}
Les balises dont vous n'êtes pas satisfait :

La méthode doSomethingElse n'est pas répertoriée dans le fichier. Dès que je commente la partie heredoc , la méthode est indexée normalement, comme vous pouvez le voir dans la section "résultat attendu" ci-dessous.

!_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
La sortie des balises que vous attendez :
!_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
La version de 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
Comment obtenez-vous le binaire ctags :

Construire localement :

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

Tous les 8 commentaires

@jespinal , parlez-vous de ce changement : 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 ce n'est pas suffisant, car le marqueur de fin devait être sur sa propre ligne , tandis que la nouvelle version lève cette restriction. Je ne trouve pas l'explication très claire :

L'implémentation que je propose évite ce problème en vérifiant si une continuation du marqueur trouvé existe, et si c'est le cas, alors s'il forme un identifiant valide.

mais je dirais que cela signifie qu'à moins qu'il n'y ait un caractère d'identification après la ligne préfixée avec le marqueur de terminaison, il s'agit bien d'un marqueur de terminaison. Donc END; est une terminaison (étant donné que le marqueur est END ), mais pas ENDFOO .

BTW, comme il s'agit d'un changement syntaxique rétrocompatible, je ne sais pas ce que nous voulons faire à ce sujet. Mais je suppose que si PHP est heureux de le casser, nous le pouvons aussi, d'autant plus qu'il est assez peu probable qu'il cause des problèmes. Idéalement, je suppose que nous utiliserions la syntaxe actuelle pour *.php[1-6] et la nouvelle pour le reste, mais cela pourrait poser trop de problèmes pour ce que cela vaut.

@jespinal , parlez-vous de ce changement : https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes ?

Désolé, @masatake , pour une raison quelconque, je n'ai pas été informé de votre question.

Oui, je parle de ce changement. Mais cela a en fait été implémenté en PHP 7.3 (la version stable actuelle est la 7.4 et la version 8 est à portée de main). Je ne sais pas pourquoi cela n'a pas été signalé plus tôt compte tenu de la vaste base d'utilisateurs des deux, ctags et PHP.

J'ajoute quelques captures d'écran d'extraits de code dérivés de l'exemple précédent afin (espérons-le) de faire la lumière sur ce qu'ils considèrent comme une syntaxe valide/invalide en ce qui concerne la nouvelle syntaxe heredoc/nowdoc (la RFC n'est pas assez claire, je pense).

Dans cet exemple, ' TEXT ' (deuxième) est le marqueur de fin. Ainsi, le troisième ' TEXT; est une chaîne syntaxiquement invalide dans la vue de l'analyseur, car il n'attendrait qu'un point-virgule ou une virgule :

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

Un cas similaire au précédent :
test-003-2020-11-24 22-37-04

Si cela avait été un point-virgule ou une virgule, l'analyseur php aurait été heureux. Par exemple

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

Aux yeux de l'analyseur, c'est la même chose que :

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

L'exemple suivant est valide, car l'analyseur sait que ' TEXT ' et ' TEXTUAL ' sont deux chaînes différentes :

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

Voici quelques extraits non valides en raison d'une mauvaise indentation. Plus précisément, à l'instruction RFC : « Si le marqueur de fermeture est indenté plus loin que toutes les lignes du corps, une ParseError sera renvoyée : »

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

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

@jespinal merci, mais si vous avez un texte normatif, c'est encore mieux :) Il est toujours difficile de deviner la logique basée uniquement sur quelques cas, alors que si nous avons le texte normatif, nous pouvons simplement l'implémenter et il devrait, espérons-le, fonctionner. Et en fait, je pense que nous en avons assez avec le lien de @masatake et vos infos :+1:

@masatake Je ne promets rien étant donné le peu de temps que j'ai trouvé ces derniers temps, mais j'essaierai d'y jeter un coup d'œil bientôt à moins que - vous ne me battez dessus :)

BTW @jespinal si personne ne s'est plaint, je pense vraiment que c'est parce qu'il y a très peu d'utilisation de cette syntaxe, et nous prenons en charge la syntaxe pré-7.3, donc les seuls cas où l'on verrait un problème sont avec l'utilisation de la syntaxe 7.3+, ce qui implique d'utiliser neredoc/nowdoc en premier lieu :)

Vous avez été inactif pendant un moment. Je ne m'attendais donc pas à recevoir un commentaire de votre part.
Mais, maintenant, nous obtenons le signe "auto-assigné" de votre part. @b4n , merci pour l'offre.

@masatake, vous étiez sage de ne pas attendre grand-chose de moi, car je n'ai effectivement pas trouvé le temps pour beaucoup de contributions UCtags/Geany ces derniers temps :déçu: . J'essaie de trouver comment répartir le temps ici, alors j'espère que je serai à nouveau plus actif, mais je ne peux pas encore promettre.

Néanmoins, voir #2734 pour un correctif pour le problème actuel :)

Merci!

Cette page vous a été utile?
0 / 5 - 0 notes