Ctags: PHP heredoc (<<

创建于 2020-11-20  ·  8评论  ·  资料来源: universal-ctags/ctags

概括:

当在文件中遇到 PHP heredoc ( <<< ) 语法时,标签生成停止。 由于nowdoc PHP 语法基本相同,这是另一种破坏文件解析的语言元素。

解析器名称:

不确定这一点。 假设 PHP

用于运行 ctags 的命令行:
$ 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的版本:
$ 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
你如何获得 ctags 二进制文件:

在本地构建它:

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

所有8条评论

@jespinal ,你是在谈论这个变化吗: 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这还不够,因为结束标记过去必须在自己的行上,而新版本取消了该限制。 我觉得解释不是很清楚:

我提议的实现通过检查找到的标记的延续是否存在来避免这个问题,如果存在,那么它是否形成一个有效的标识符。

但我会说这意味着除非在以终止标记为前缀的行后面有一个标识符字符,否则它确实是一个终止标记。 所以END;是一个终止(假设标记是END ),但ENDFOO不是。

顺便说一句,由于这是一个向后不兼容的语法更改,我不知道我们想对此做些什么。 但我想如果 PHP 乐于打破它,我们也可以,特别是因为它不太可能引起问题。 理想情况下,我想我们会对*.php[1-6]使用当前的语法,而对于其余的则使用新的语法,但这对于它的价值来说可能太麻烦了。

@jespinal ,你是在谈论这个变化吗: https : //wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes

抱歉, @masatake ,出于某种原因,我没有收到您的问题的通知。

是的,我说的是这种变化。 但这实际上是在 PHP 7.3 中实现的(当前稳定版本是 7.4,版本 8 即将推出)。 考虑到 ctags 和 PHP 的庞大用户群,我不确定为什么没有更早地报告这一点。

我正在添加一些从上一个示例派生的代码片段的屏幕截图,以便(希望)阐明他们认为关于新的 heredoc/nowdoc 语法的有效/无效语法(RFC 不够清楚,我思考)。

在此示例中,“ TEXT ”(第二个)是结束标记。 因此,第三个 ' TEXT;在解析器看来是一个语法上无效的字符串,因为它只需要一个分号或逗号:

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

与上一个类似的案例:
test-003-2020-11-24 22-37-04

如果它是分号或逗号,php 解析器会很高兴。 例如

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

在解析器的眼中,这与:

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

下面是一个有效的例子,因为解析器知道 ' TEXT ' 和 ' TEXTUAL ' 是两个不同的字符串:

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

由于缩进错误,这里有几个无效的片段。 具体来说,对于 RFC 语句:“如果结束标记比正文的任何​​行缩进得更远,则将抛出 ParseError:”

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

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

@jespinal谢谢,但如果你有规范性文本,那就更好了 :) 仅仅基于少数情况来猜测逻辑总是很棘手,而如果我们有规范性文本,我们就可以实现它,它应该有希望工作。 实际上,我认为@masatake的链接和您的信息已经足够了:+1:

@masatake鉴于我最近发现的时间很少,我不承诺任何事情,但我会尽快尝试一下,除非 - 你打败了我:)

顺便说一句@jespinal如果没有人抱怨我真的认为这是因为这些语法的使用很少,而且我们支持 7.3 之前的语法,所以唯一会看到问题的情况是 7.3+ 语法使用,这意味着使用 neredoc/nowdoc首先:)

你有一段时间没有活动。 所以我没想到会得到你的评论。
但是,现在我们从你那里得到了“自我分配”的标志。 @b4n ,谢谢你的奉献。

@masatake明智的做法是不要对我期望太多,因为我最近确实没有时间为 UCtags/Geany 做出很多贡献:失望:。 我正在努力寻找如何再次分配时间,所以我希望我能再次活跃起来,但我现在还不能保证。

尽管如此,请参阅 #2734 以修复手头的问题:)

谢谢!

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

相关问题

jagjordi picture jagjordi  ·  9评论

fommil picture fommil  ·  19评论

JulienPivard picture JulienPivard  ·  16评论

softinio picture softinio  ·  6评论

cweagans picture cweagans  ·  13评论