Visual Studio 语言扩展的代码提供者

Visual Studio Code Providers for language extension

我正在尝试学习如何实现一些帮助提供程序:自动完成、签名帮助和悬停。

我正在为一个框架做这件事,据我所知,它不能在其主应用程序之外执行,所以我想解决这个问题(获取对象类型、方法和文档)的一种方法是解析其文档。

例如悬停提供者;一旦光标悬停在单词上,我就可以在文档中搜索它并显示结果:

class HSHoverProvider implements vscode.HoverProvider {
    public provideSignatureHelp(
        document: vscode.TextDocument,
        position: vscode.Position,
        token: vscode.CancellationToken
    ): vscode.SignatureHelp {
        // get current word/line under the cursor and find a match inside the docs
        ...
        return new vscode.Hover(data);
    }
}

...

context.subscriptions.push(
    vscode.languages.registerHoverProvider("lua", new HSHoverProvider())
);

当操作直接在初始声明上时,这会很好地工作。我可以直接解析该行并使用正则表达式找到我需要的内容。

-- hovering over `application`, I check the context with a regex.
local app = hs.application('Code')

但是,当涉及到“参考”时,我遇到了困难。使用正则表达式方法在文档中搜索 app 的声明会导致许多边缘情况,主要是因为声明范围:

示例:

-- declaration target
local app = hs.application('Code')

local function foo()
    local app = hs.pasteboard()
end

local function bar()
    if 'foo' then
        local app = hs.alert() 
    end

    do local app = hs.window.focusedWindow() end

    -- a regex will have a hard time to understand which declaration is correct
   print(app:title())
end

这让我认为正则表达式不是合适的解决方案。我还认为实施 vscode.DefinitionProvider 会给我一些见解,但事实并非如此。

我试图查看其他已经做同样事情的扩展(主要是 sumneko 的 Lua Language Server),但我无法理解他们是如何做到的(除了他们使用语言服务器方法)。

我怎么会去做这样的事情?我需要一棵 AST 树并从那里检查吗?使用语言服务器会是更好的选择吗?我是错过了一个更大的图景,还是我只需要一个更强大的文档解析器?

如有任何见解,我们将不胜感激。提前致谢

在这种情况下通常的方法是创建一个符号 table。您首先要解析要为其提供工具的代码。从解析树(或语法树,取决于所使用的解析器工具)生成你的符号 table,它包含你需要的信息,包括块和符号的嵌套、符号的类型(例如对象名称或对象引用)和符号有效的范围。