Генерация тегов останавливается, когда в файле встречается синтаксис PHP heredoc
( <<<
). Поскольку синтаксис nowdoc
PHP в основном тот же, это еще один языковой элемент, который нарушает синтаксический анализ файла.
не уверен в этом. Предполагая, что PHP
$ ctags --options=NONE foo.php
<?php
class LivingBeings {
public function doSomething()
{
$foo = <<<FOO
FOO;
}
public function doSomethingElse()
{
}
}
Метод doSomethingElse
не указан в файле. Как только я закомментирую часть heredoc
, метод индексируется нормально, как вы можете видеть в разделе «Ожидаемый результат» впереди.
!_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
!_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
$ 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
Сборка локально:
$ cd ctags_source
$ make clean && make distclean
$ ./autogen.sh
$ ./configure --prefix=$HOME
$ make
$ make install
@jespinal , вы говорите об этом изменении: https://wiki.php.net/rfc/f 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 этого недостаточно, потому что конечный маркер раньше должен был находиться на отдельной строке , а в новой версии это ограничение снимается. Я не нахожу объяснение очень ясным:
Предлагаемая мной реализация позволяет избежать этой проблемы, проверяя, существует ли продолжение найденного маркера, и если да, то формирует ли он действительный идентификатор.
но я бы сказал, что это означает, что если после строки с префиксом завершающего маркера нет символа идентификатора, это действительно конечный маркер. Итак, END;
- это завершение (учитывая, что маркер - END
), а ENDFOO
- нет.
Кстати, поскольку это обратно несовместимое синтаксическое изменение, я не знаю, что мы хотим с этим делать. Но я думаю, что если PHP будет рад сломать его, мы тоже сможем, тем более что это вряд ли вызовет проблемы. В идеале, я думаю, мы бы использовали текущий синтаксис для *.php[1-6]
и новый для остальных, но это может быть слишком большой проблемой для того, чего он стоит.
@jespinal , вы говорите об этом изменении: https://wiki.php.net/rfc/f flexible_heredoc_nowdoc_syntaxes ?
Извините, @masatake , по какой-то причине меня не уведомили о вашем вопросе.
Да, я говорю об этом изменении. Но на самом деле это было реализовано в PHP 7.3 (текущая стабильная версия - 7.4, и версия 8 уже под рукой). Я не уверен, почему об этом не сообщалось ранее, учитывая обширную базу пользователей как ctags, так и PHP.
Я добавляю несколько скриншотов фрагментов кода, взятых из предыдущего примера, чтобы (надеюсь) пролить свет на то, что они считают допустимым / недопустимым синтаксисом в отношении нового синтаксиса heredoc / nowdoc (RFC недостаточно ясен, я считать).
В этом примере ' TEXT
' (второй) - конечный маркер. Итак, третья строка ' TEXT;
является синтаксически недопустимой строкой в представлении парсера, так как она ожидает только точку с запятой или запятую:
Случай, аналогичный предыдущему:
Будь то точка с запятой или запятая, парсер php был бы счастлив. Например
echo <<<TEXT
some string
TEXT, 'some other string';
В глазах парсера это то же самое, что:
echo 'some string', 'some other string';
Ниже приведен допустимый пример, поскольку синтаксический анализатор знает, что « TEXT
» и « TEXTUAL
- это две разные строки:
Вот пара недействительных фрагментов из-за неправильного отступа. В частности, к заявлению RFC: «Если закрывающий маркер смещен дальше, чем любая строка тела, то будет выдано исключение ParseError:»
@jespinal, спасибо, но если у вас есть нормативный текст, это будет еще лучше :) Всегда сложно угадать логику, основанную исключительно на нескольких случаях, тогда как, если у нас есть нормативный текст, мы можем просто реализовать это, и мы надеемся, что это сработает. На самом деле, я думаю, нам достаточно ссылки @masatake и вашей информации: +1:
@masatake Я ничего не обещаю, учитывая то небольшое количество времени, которое я нахожу в последнее время, но я постараюсь в ближайшее время взглянуть на это, если - вы меня не опередите :)
Кстати, @jespinal, если никто не жаловался, я действительно думаю, это потому, что этот синтаксис используется очень мало, и мы поддерживаем синтаксис до 7.3, поэтому единственные случаи, когда можно было бы увидеть проблему, - это использование синтаксиса 7.3+, что подразумевает использование neredoc / nowdoc в первую очередь :)
Вы какое-то время бездействовали. Так что я не ожидал получить от вас комментарий.
Но, теперь мы получаем от вас знак "самопровозглашенный". @ b4n , спасибо за предложение.
@masatake, вы
Тем не менее, см. # 2734 для исправления проблемы :)
Спасибо!