如何在 LSP 中实现上下文访问实现?



很难确切地解释我所说的上下文go-to-implementation是什么意思,所以在Rust中采用以下示例代码:

struct A {}
struct B {}
impl From<A> for B {
fn from(a: A) -> Self {
B{}
}
}
fn fun() -> B {
let a = A{};
a.into()
}

能够将光标放在fun最后一行对into()的调用上,并期望能够轻松转到From<A> for Bfrom()的定义(期望看到a(类型A)如何成为B型的东西)对我来说似乎很有用。 真正发生的是去实现请求将我带到标准库中的通用实现:

// From implies Into
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
impl<T, U> const Into<U> for T
where
U: ~const From<T>,
{
/// Calls `U::from(self)`.
///
/// That is, this conversion is whatever the implementation of
/// <code>[From]&lt;T&gt; for U</code> chooses to do.
fn into(self) -> U { // <- I'm taken here
U::from(self)
}
}

这是正确的。但是,上下文丢失了,现在无法从下面的行返回到源代码中的实际目标,因为有许多From实现。LSP 的实现可以确切地知道,在最近的跳跃上下文中,T=AU=B,因此:

  1. 编辑器可以暂时将此上下文显示为内联提示(直到上下文重置),
  2. 在下一个转到实现请求中,上下文可用于知道给定上下文(TU)只有一个From实现,并专门跳转到行:fn from(a: A) -> Self {

此功能的实现是否需要更改协议定义本身? 协议中是否有任何用于处理通用代码的功能可以指出我正确的方法?

转到实现功能在 https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_implementation 中描述

看起来请求被传递ImplementationParams其中包含要检索其实现的位置。

LocationLink数组可用于传递多个先前的 go-to-implementation请求(或者,实际上是任何 go-to-* 请求)的上下文,这将允许语言服务器根据包含某种类型实例化的上下文限制返回的LocationLink数。

因此,是的,协议需要扩展以支持此功能。

还有另一种可能。go-to-* 上下文堆栈可以在服务器中维护,每个 go-to-* 请求都会将新的上下文推送到堆栈上。对此堆栈的分析将允许服务器在上下文中限制建议的 go-to-* 位置列表,但它也允许它根据首选上下文堆栈以不同的方式生成代码提示/诊断,包括用于上下文类型具体化的新型提示/悬停。 到目前为止,它不需要修改协议。但实际上,至少需要弹出和清除堆栈的方法。

可以通过定义新的服务器和客户端功能来实现向后兼容性。

最新更新