els/
implementation.rs

1use erg_compiler::artifact::BuildRunnable;
2use erg_compiler::erg_parser::parse::Parsable;
3use lsp_types::request::{GotoImplementationParams, GotoImplementationResponse};
4
5use crate::_log;
6use crate::server::{ELSResult, RedirectableStdout, Server};
7use crate::util::{loc_to_pos, NormalizedUrl};
8
9impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
10    pub(crate) fn handle_goto_implementation(
11        &mut self,
12        params: GotoImplementationParams,
13    ) -> ELSResult<Option<GotoImplementationResponse>> {
14        _log!(self, "implementation requested: {params:?}");
15        let uri = NormalizedUrl::new(params.text_document_position_params.text_document.uri);
16        let pos = params.text_document_position_params.position;
17        let Some(symbol) = self.file_cache.get_symbol(&uri, pos) else {
18            return Ok(None);
19        };
20        // {x #[ ← this is not the impl ]#;} = import "foo"
21        // print! x # ← symbol
22        if let Some(vi) = self.get_definition(&uri, &symbol)? {
23            let Some(uri) = vi
24                .def_loc
25                .module
26                .and_then(|p| NormalizedUrl::from_file_path(p).ok())
27            else {
28                return Ok(None);
29            };
30            let Some(pos) = loc_to_pos(vi.def_loc.loc) else {
31                return Ok(None);
32            };
33            if let Some(location) = self.get_definition_location(&uri, pos)? {
34                return Ok(Some(GotoImplementationResponse::Scalar(location)));
35            }
36        }
37        Ok(None)
38    }
39}