dev: convert all syntax-level request and check main state before requesting (#67)

This commit is contained in:
Myriad-Dreamin 2024-03-18 17:36:43 +08:00 committed by GitHub
parent 5d123221db
commit 2fe992e933
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 78 additions and 85 deletions

View file

@ -1,6 +1,6 @@
use lsp_types::Command;
use crate::prelude::*;
use crate::{prelude::*, SyntaxRequest};
/// The [`textDocument/codeLens`] request is sent from the client to the server
/// to compute code lenses for a given text document.
@ -12,15 +12,13 @@ pub struct CodeLensRequest {
pub path: PathBuf,
}
impl CodeLensRequest {
pub fn request(
self,
world: &TypstSystemWorld,
position_encoding: PositionEncoding,
) -> Option<Vec<CodeLens>> {
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
impl SyntaxRequest for CodeLensRequest {
type Response = Vec<CodeLens>;
let doc_start = typst_to_lsp::range(0..0, &source, position_encoding);
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response> {
let source = ctx.source_by_path(&self.path).ok()?;
let doc_start = ctx.to_lsp_range(0..0, &source);
let mut res = vec![];

View file

@ -6,6 +6,7 @@ use lsp_types::LocationLink;
use crate::{
prelude::*,
syntax::{get_deref_target, DerefTarget},
SyntaxRequest,
};
#[derive(Debug, Clone)]
@ -14,36 +15,31 @@ pub struct GotoDeclarationRequest {
pub position: LspPosition,
}
impl GotoDeclarationRequest {
pub fn request(
self,
world: &TypstSystemWorld,
position_encoding: PositionEncoding,
) -> Option<GotoDeclarationResponse> {
let mut ctx = AnalysisContext::new(world, position_encoding);
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
let offset = lsp_to_typst::position(self.position, position_encoding, &source)?;
impl SyntaxRequest for GotoDeclarationRequest {
type Response = GotoDeclarationResponse;
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response> {
let source = ctx.source_by_path(&self.path).ok()?;
let offset = ctx.to_typst_pos(self.position, &source)?;
let cursor = offset + 1;
let w: &dyn World = world;
let ast_node = LinkedNode::new(source.root()).leaf_at(cursor)?;
debug!("ast_node: {ast_node:?}", ast_node = ast_node);
let deref_target = get_deref_target(ast_node)?;
let use_site = deref_target.node();
let origin_selection_range =
typst_to_lsp::range(use_site.range(), &source, position_encoding);
let origin_selection_range = ctx.to_lsp_range(use_site.range(), &source);
let def_use = ctx.def_use(source.clone())?;
let ref_spans = find_declarations(w, def_use, deref_target)?;
let ref_spans = find_declarations(ctx, def_use, deref_target)?;
let mut links = vec![];
for ref_range in ref_spans {
let ref_id = source.id();
let ref_source = &source;
let span_path = world.path_for_id(ref_id).ok()?;
let range = typst_to_lsp::range(ref_range, ref_source, position_encoding);
let span_path = ctx.world.path_for_id(ref_id).ok()?;
let range = ctx.to_lsp_range(ref_range, ref_source);
let uri = Url::from_file_path(span_path).ok()?;
@ -61,7 +57,7 @@ impl GotoDeclarationRequest {
}
fn find_declarations(
_w: &dyn World,
_ctx: &AnalysisContext,
_def_use: Arc<crate::analysis::DefUseInfo>,
_deref_target: DerefTarget<'_>,
) -> Option<Vec<Range<usize>>> {

View file

@ -9,7 +9,7 @@ use typst::{
};
use typst_ts_core::typst::prelude::eco_vec;
use crate::prelude::*;
use crate::{prelude::*, SyntaxRequest};
pub struct InlayHintConfig {
// positional arguments group
@ -45,16 +45,14 @@ pub struct InlayHintRequest {
pub range: LspRange,
}
impl InlayHintRequest {
pub fn request(
self,
world: &TypstSystemWorld,
position_encoding: PositionEncoding,
) -> Option<Vec<InlayHint>> {
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
let range = lsp_to_typst::range(self.range, position_encoding, &source)?;
impl SyntaxRequest for InlayHintRequest {
type Response = Vec<InlayHint>;
let hints = inlay_hint(world, &source, range, position_encoding).ok()?;
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response> {
let source = ctx.source_by_path(&self.path).ok()?;
let range = ctx.to_typst_range(self.range, &source)?;
let hints = inlay_hint(ctx.world, &source, range, ctx.position_encoding()).ok()?;
debug!(
"got inlay hints on {source:?} => {hints:?}",
source = source.id(),
@ -663,8 +661,8 @@ mod tests {
#[test]
fn smart() {
snapshot_testing("inlay_hints", &|world, path| {
let source = get_suitable_source_in_workspace(world, &path).unwrap();
snapshot_testing2("inlay_hints", &|ctx, path| {
let source = ctx.source_by_path(&path).unwrap();
let request = InlayHintRequest {
path: path.clone(),
@ -675,7 +673,7 @@ mod tests {
),
};
let result = request.request(world, PositionEncoding::Utf16);
let result = request.request(ctx);
assert_snapshot!(JsonRepr::new_redacted(result, &REDACT_LOC));
});
}

View file

@ -1,4 +1,4 @@
use crate::prelude::*;
use crate::{prelude::*, SyntaxRequest};
#[derive(Debug, Clone)]
pub struct SignatureHelpRequest {
@ -6,14 +6,12 @@ pub struct SignatureHelpRequest {
pub position: LspPosition,
}
impl SignatureHelpRequest {
pub fn request(
self,
world: &TypstSystemWorld,
position_encoding: PositionEncoding,
) -> Option<SignatureHelp> {
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
let typst_offset = lsp_to_typst::position(self.position, position_encoding, &source)?;
impl SyntaxRequest for SignatureHelpRequest {
type Response = SignatureHelp;
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response> {
let source = ctx.source_by_path(&self.path).ok()?;
let typst_offset = ctx.to_typst_pos(self.position, &source)?;
let ast_node = LinkedNode::new(source.root()).leaf_at(typst_offset + 1)?;
let (callee, callee_node, args) = surrounding_function_syntax(&ast_node)?;
@ -22,7 +20,7 @@ impl SignatureHelpRequest {
return None;
}
let values = analyze_expr(world, &callee_node);
let values = analyze_expr(ctx.world, &callee_node);
let function = values.into_iter().find_map(|v| match v.0 {
Value::Func(f) => Some(f),

View file

@ -3,6 +3,7 @@ use typst_ts_compiler::NotifyApi;
use crate::{
prelude::*,
syntax::{get_lexical_hierarchy, LexicalHierarchy, LexicalScopeKind},
SyntaxRequest,
};
#[derive(Debug, Clone)]
@ -10,25 +11,29 @@ pub struct SymbolRequest {
pub pattern: Option<String>,
}
impl SymbolRequest {
pub fn request(
self,
world: &TypstSystemWorld,
position_encoding: PositionEncoding,
) -> Option<Vec<SymbolInformation>> {
impl SyntaxRequest for SymbolRequest {
type Response = Vec<SymbolInformation>;
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response> {
// todo: expose source
let mut symbols = vec![];
world.iter_dependencies(&mut |path, _| {
let Ok(source) = get_suitable_source_in_workspace(world, path) else {
ctx.world.iter_dependencies(&mut |path, _| {
let Ok(source) = ctx.source_by_path(path) else {
return;
};
let uri = Url::from_file_path(path).unwrap();
let res = get_lexical_hierarchy(source.clone(), LexicalScopeKind::Symbol).and_then(
|symbols| {
self.pattern.as_ref().map(|pattern| {
filter_document_symbols(&symbols, pattern, &source, &uri, position_encoding)
filter_document_symbols(
&symbols,
pattern,
&source,
&uri,
ctx.position_encoding(),
)
})
},
);