mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 13:13:43 +00:00
dev: stateful requests now accept snapshot (#1581)
* dev: stateful requests now accept snapshot * dev: add some convenient methods * dev: remove unused latest_doc state * dev: use graph * docs: comment * fix: bad flag
This commit is contained in:
parent
5b42231a77
commit
10ec787cc9
29 changed files with 383 additions and 504 deletions
|
@ -1,5 +1,6 @@
|
|||
//! Linked definition analysis
|
||||
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use typst::foundations::{IntoValue, Label, Selector, Type};
|
||||
use typst::introspection::Introspector;
|
||||
use typst::model::BibliographyElem;
|
||||
|
@ -7,7 +8,6 @@ use typst::model::BibliographyElem;
|
|||
use super::{prelude::*, InsTy, SharedContext};
|
||||
use crate::syntax::{Decl, DeclExpr, Expr, ExprInfo, SyntaxClass, VarClass};
|
||||
use crate::ty::DocSource;
|
||||
use crate::VersionedDocument;
|
||||
|
||||
/// A linked definition in the source code
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
|
@ -59,7 +59,7 @@ impl Definition {
|
|||
pub fn definition(
|
||||
ctx: &Arc<SharedContext>,
|
||||
source: &Source,
|
||||
document: Option<&VersionedDocument>,
|
||||
document: Option<&TypstDocument>,
|
||||
syntax: SyntaxClass,
|
||||
) -> Option<Definition> {
|
||||
match syntax {
|
||||
|
@ -81,7 +81,7 @@ pub fn definition(
|
|||
_ => return None,
|
||||
};
|
||||
|
||||
let introspector = &document?.document.introspector();
|
||||
let introspector = &document?.introspector();
|
||||
bib_definition(ctx, introspector, name)
|
||||
.or_else(|| ref_definition(introspector, name, ref_expr))
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use rustc_hash::FxHashMap;
|
|||
use tinymist_project::LspWorld;
|
||||
use tinymist_std::debug_loc::DataSource;
|
||||
use tinymist_std::hash::{hash128, FxDashMap};
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use tinymist_world::vfs::{PathResolution, WorkspaceResolver};
|
||||
use tinymist_world::{EntryReader, DETACHED_ENTRY};
|
||||
use typst::diag::{eco_format, At, FileError, FileResult, SourceResult, StrResult};
|
||||
|
@ -37,7 +38,6 @@ use crate::syntax::{
|
|||
use crate::upstream::{tooltip_, Tooltip};
|
||||
use crate::{
|
||||
ColorTheme, CompilerQueryRequest, LspPosition, LspRange, LspWorldExt, PositionEncoding,
|
||||
VersionedDocument,
|
||||
};
|
||||
|
||||
use super::TypeEnv;
|
||||
|
@ -195,7 +195,7 @@ pub trait PeriscopeProvider {
|
|||
fn periscope_at(
|
||||
&self,
|
||||
_ctx: &mut LocalContext,
|
||||
_doc: VersionedDocument,
|
||||
_doc: &TypstDocument,
|
||||
_pos: Position,
|
||||
) -> Option<String> {
|
||||
None
|
||||
|
@ -796,7 +796,7 @@ impl SharedContext {
|
|||
pub(crate) fn def_of_span(
|
||||
self: &Arc<Self>,
|
||||
source: &Source,
|
||||
doc: Option<&VersionedDocument>,
|
||||
doc: Option<&TypstDocument>,
|
||||
span: Span,
|
||||
) -> Option<Definition> {
|
||||
let syntax = self.classify_span(source, span)?;
|
||||
|
@ -814,7 +814,7 @@ impl SharedContext {
|
|||
pub(crate) fn def_of_syntax(
|
||||
self: &Arc<Self>,
|
||||
source: &Source,
|
||||
doc: Option<&VersionedDocument>,
|
||||
doc: Option<&TypstDocument>,
|
||||
syntax: SyntaxClass,
|
||||
) -> Option<Definition> {
|
||||
definition(self, source, doc, syntax)
|
||||
|
|
|
@ -41,11 +41,7 @@ pub struct CompletionRequest {
|
|||
impl StatefulRequest for CompletionRequest {
|
||||
type Response = CompletionList;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
// These trigger characters are for completion on positional arguments,
|
||||
// which follows the configuration item
|
||||
// `tinymist.completion.triggerOnSnippetPlaceholders`.
|
||||
|
@ -55,7 +51,7 @@ impl StatefulRequest for CompletionRequest {
|
|||
return None;
|
||||
}
|
||||
|
||||
let document = doc.as_ref().map(|doc| &doc.document);
|
||||
let document = graph.snap.success_doc.as_ref();
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let cursor = ctx.to_typst_pos_offset(&source, self.position, 0)?;
|
||||
|
||||
|
@ -134,7 +130,7 @@ mod tests {
|
|||
let mut includes = HashSet::new();
|
||||
let mut excludes = HashSet::new();
|
||||
|
||||
let doc = compile_doc_for_test(ctx, &properties);
|
||||
let graph = compile_doc_for_test(ctx, &properties);
|
||||
|
||||
for kk in properties.get("contains").iter().flat_map(|v| v.split(',')) {
|
||||
// split first char
|
||||
|
@ -188,7 +184,7 @@ mod tests {
|
|||
trigger_character,
|
||||
};
|
||||
let result = request
|
||||
.request(ctx, doc.clone())
|
||||
.request(ctx, graph.clone())
|
||||
.map(|list| CompletionList {
|
||||
is_incomplete: list.is_incomplete,
|
||||
items: get_items(list.items),
|
||||
|
|
|
@ -98,13 +98,8 @@ pub struct DocumentMetricsRequest {
|
|||
impl StatefulRequest for DocumentMetricsRequest {
|
||||
type Response = DocumentMetricsResponse;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
let doc = doc?;
|
||||
let doc = doc.document;
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.as_ref()?;
|
||||
|
||||
let mut worker = DocumentMetricsWorker {
|
||||
ctx,
|
||||
|
@ -113,7 +108,7 @@ impl StatefulRequest for DocumentMetricsRequest {
|
|||
font_info: Default::default(),
|
||||
};
|
||||
|
||||
worker.work(&doc)?;
|
||||
worker.work(doc)?;
|
||||
|
||||
let font_info = worker.compute()?;
|
||||
let span_info = SpanInfo {
|
||||
|
|
|
@ -26,16 +26,13 @@ pub struct GotoDefinitionRequest {
|
|||
impl StatefulRequest for GotoDefinitionRequest {
|
||||
type Response = GotoDefinitionResponse;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.as_ref();
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let syntax = ctx.classify_for_decl(&source, self.position)?;
|
||||
let origin_selection_range = ctx.to_lsp_range(syntax.node().range(), &source);
|
||||
|
||||
let def = ctx.def_of_syntax(&source, doc.as_ref(), syntax)?;
|
||||
let def = ctx.def_of_syntax(&source, doc, syntax)?;
|
||||
|
||||
let (fid, def_range) = def.location(ctx.shared())?;
|
||||
let uri = ctx.uri_for_id(fid).ok()?;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use core::fmt::{self, Write};
|
||||
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use typst::foundations::repr::separated_list;
|
||||
use typst_shim::syntax::LinkedNodeExt;
|
||||
|
||||
|
@ -26,11 +27,8 @@ pub struct HoverRequest {
|
|||
impl StatefulRequest for HoverRequest {
|
||||
type Response = Hover;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.clone();
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let offset = ctx.to_typst_pos(self.position, &source)?;
|
||||
// the typst's cursor is 1-based, so we need to add 1 to the offset
|
||||
|
@ -80,7 +78,7 @@ impl StatefulRequest for HoverRequest {
|
|||
struct HoverWorker<'a> {
|
||||
ctx: &'a mut LocalContext,
|
||||
source: Source,
|
||||
doc: Option<VersionedDocument>,
|
||||
doc: Option<TypstDocument>,
|
||||
cursor: usize,
|
||||
def: Vec<String>,
|
||||
value: Vec<String>,
|
||||
|
@ -250,19 +248,19 @@ impl HoverWorker<'_> {
|
|||
// Preview results
|
||||
let provider = self.ctx.analysis.periscope.clone()?;
|
||||
let doc = self.doc.as_ref()?;
|
||||
let position = jump_from_cursor(&doc.document, &self.source, self.cursor);
|
||||
let position = jump_from_cursor(doc, &self.source, self.cursor);
|
||||
let position = position.or_else(|| {
|
||||
for idx in 1..100 {
|
||||
let next_cursor = self.cursor + idx;
|
||||
if next_cursor < self.source.text().len() {
|
||||
let position = jump_from_cursor(&doc.document, &self.source, next_cursor);
|
||||
let position = jump_from_cursor(doc, &self.source, next_cursor);
|
||||
if position.is_some() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
let prev_cursor = self.cursor.checked_sub(idx);
|
||||
if let Some(prev_cursor) = prev_cursor {
|
||||
let position = jump_from_cursor(&doc.document, &self.source, prev_cursor);
|
||||
let position = jump_from_cursor(doc, &self.source, prev_cursor);
|
||||
if position.is_some() {
|
||||
return position;
|
||||
}
|
||||
|
@ -274,7 +272,7 @@ impl HoverWorker<'_> {
|
|||
|
||||
log::info!("telescope position: {position:?}");
|
||||
|
||||
let preview_content = provider.periscope_at(self.ctx, doc.clone(), position?)?;
|
||||
let preview_content = provider.periscope_at(self.ctx, doc, position?)?;
|
||||
self.preview.push(preview_content);
|
||||
Some(())
|
||||
}
|
||||
|
@ -390,15 +388,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test() {
|
||||
snapshot_testing("hover", &|world, path| {
|
||||
let source = world.source_by_path(&path).unwrap();
|
||||
snapshot_testing("hover", &|ctx, path| {
|
||||
let source = ctx.source_by_path(&path).unwrap();
|
||||
|
||||
let request = HoverRequest {
|
||||
path: path.clone(),
|
||||
position: find_test_position(&source),
|
||||
};
|
||||
|
||||
let result = request.request(world, None);
|
||||
let snap = WorldComputeGraph::from_world(ctx.world.clone());
|
||||
let result = request.request(ctx, snap);
|
||||
assert_snapshot!(JsonRepr::new_redacted(result, &REDACT_LOC));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,97 +7,88 @@
|
|||
//! code. Currently it provides:
|
||||
//! + language queries defined by the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/).
|
||||
|
||||
mod adt;
|
||||
pub use analysis::{CompletionFeat, LocalContext, LocalContextGuard, LspWorldExt};
|
||||
pub use completion::{CompletionRequest, PostfixSnippet};
|
||||
pub use typlite::ColorTheme;
|
||||
pub use upstream::with_vm;
|
||||
|
||||
pub use code_action::*;
|
||||
pub use code_context::*;
|
||||
pub use code_lens::*;
|
||||
pub use color_presentation::*;
|
||||
pub use diagnostics::*;
|
||||
pub use document_color::*;
|
||||
pub use document_highlight::*;
|
||||
pub use document_link::*;
|
||||
pub use document_metrics::*;
|
||||
pub use document_symbol::*;
|
||||
pub use folding_range::*;
|
||||
pub use goto_declaration::*;
|
||||
pub use goto_definition::*;
|
||||
pub use hover::*;
|
||||
pub use inlay_hint::*;
|
||||
pub use jump::*;
|
||||
pub use lsp_typst_boundary::*;
|
||||
pub use on_enter::*;
|
||||
pub use prepare_rename::*;
|
||||
pub use references::*;
|
||||
pub use rename::*;
|
||||
pub use selection_range::*;
|
||||
pub use semantic_tokens_delta::*;
|
||||
pub use semantic_tokens_full::*;
|
||||
pub use signature_help::*;
|
||||
pub use symbol::*;
|
||||
pub use will_rename_files::*;
|
||||
pub use workspace_label::*;
|
||||
|
||||
pub mod analysis;
|
||||
pub mod docs;
|
||||
pub mod package;
|
||||
pub mod syntax;
|
||||
pub mod testing;
|
||||
pub mod ty;
|
||||
mod upstream;
|
||||
|
||||
pub use analysis::{CompletionFeat, LocalContext, LocalContextGuard, LspWorldExt};
|
||||
pub use completion::PostfixSnippet;
|
||||
pub use upstream::with_vm;
|
||||
|
||||
mod diagnostics;
|
||||
pub use diagnostics::*;
|
||||
mod code_action;
|
||||
pub use code_action::*;
|
||||
mod code_context;
|
||||
pub use code_context::*;
|
||||
mod code_lens;
|
||||
pub use code_lens::*;
|
||||
mod completion;
|
||||
pub use completion::CompletionRequest;
|
||||
mod color_presentation;
|
||||
pub use color_presentation::*;
|
||||
mod document_color;
|
||||
pub use document_color::*;
|
||||
mod document_highlight;
|
||||
pub use document_highlight::*;
|
||||
mod document_symbol;
|
||||
pub use document_symbol::*;
|
||||
mod document_link;
|
||||
pub use document_link::*;
|
||||
mod workspace_label;
|
||||
pub use workspace_label::*;
|
||||
mod document_metrics;
|
||||
pub use document_metrics::*;
|
||||
mod folding_range;
|
||||
pub use folding_range::*;
|
||||
mod goto_declaration;
|
||||
pub use goto_declaration::*;
|
||||
mod goto_definition;
|
||||
pub use goto_definition::*;
|
||||
mod hover;
|
||||
pub use hover::*;
|
||||
mod inlay_hint;
|
||||
pub use inlay_hint::*;
|
||||
mod jump;
|
||||
pub use jump::*;
|
||||
mod will_rename_files;
|
||||
pub use will_rename_files::*;
|
||||
mod rename;
|
||||
pub use rename::*;
|
||||
mod selection_range;
|
||||
pub use selection_range::*;
|
||||
mod semantic_tokens_full;
|
||||
pub use semantic_tokens_full::*;
|
||||
mod semantic_tokens_delta;
|
||||
pub use semantic_tokens_delta::*;
|
||||
mod signature_help;
|
||||
pub use signature_help::*;
|
||||
mod symbol;
|
||||
pub use symbol::*;
|
||||
mod on_enter;
|
||||
pub use on_enter::*;
|
||||
mod prepare_rename;
|
||||
pub use prepare_rename::*;
|
||||
mod references;
|
||||
pub use references::*;
|
||||
|
||||
mod lsp_typst_boundary;
|
||||
pub use lsp_typst_boundary::*;
|
||||
|
||||
mod prelude;
|
||||
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use typst::syntax::Source;
|
||||
|
||||
/// The physical position in a document.
|
||||
pub type FramePosition = typst::layout::Position;
|
||||
|
||||
pub use typlite::ColorTheme;
|
||||
mod adt;
|
||||
mod lsp_typst_boundary;
|
||||
mod prelude;
|
||||
|
||||
/// A compiled document with an self-incremented logical version.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VersionedDocument {
|
||||
/// The version of the document.
|
||||
pub version: usize,
|
||||
/// The compiled document.
|
||||
pub document: TypstDocument,
|
||||
}
|
||||
mod code_action;
|
||||
mod code_context;
|
||||
mod code_lens;
|
||||
mod color_presentation;
|
||||
mod completion;
|
||||
mod diagnostics;
|
||||
mod document_color;
|
||||
mod document_highlight;
|
||||
mod document_link;
|
||||
mod document_metrics;
|
||||
mod document_symbol;
|
||||
mod folding_range;
|
||||
mod goto_declaration;
|
||||
mod goto_definition;
|
||||
mod hover;
|
||||
mod inlay_hint;
|
||||
mod jump;
|
||||
mod on_enter;
|
||||
mod prepare_rename;
|
||||
mod references;
|
||||
mod rename;
|
||||
mod selection_range;
|
||||
mod semantic_tokens_delta;
|
||||
mod semantic_tokens_full;
|
||||
mod signature_help;
|
||||
mod symbol;
|
||||
mod upstream;
|
||||
mod will_rename_files;
|
||||
mod workspace_label;
|
||||
|
||||
use typst::syntax::Source;
|
||||
|
||||
use tinymist_analysis::log_debug_ct;
|
||||
use tinymist_project::LspComputeGraph;
|
||||
|
||||
/// A request handler with given syntax information.
|
||||
pub trait SyntaxRequest {
|
||||
|
@ -121,22 +112,16 @@ pub trait SemanticRequest {
|
|||
fn request(self, ctx: &mut LocalContext) -> Option<Self::Response>;
|
||||
}
|
||||
|
||||
/// A request handler with given (semantic) analysis context and a versioned
|
||||
/// document.
|
||||
/// A request handler with given (semantic) analysis context and a project
|
||||
/// snapshot.
|
||||
pub trait StatefulRequest {
|
||||
/// The response type of the request.
|
||||
type Response;
|
||||
|
||||
/// Request the information from the given context.
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response>;
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response>;
|
||||
}
|
||||
|
||||
use tinymist_analysis::log_debug_ct;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
mod polymorphic {
|
||||
use completion::CompletionList;
|
||||
|
|
|
@ -17,6 +17,7 @@ pub use lsp_types::{
|
|||
SignatureHelp, SignatureInformation, SymbolInformation, TextEdit, Url, WorkspaceEdit,
|
||||
};
|
||||
pub use serde_json::Value as JsonValue;
|
||||
pub use tinymist_project::LspComputeGraph;
|
||||
pub use tinymist_std::DefId;
|
||||
pub use typst::diag::{EcoString, Tracepoint};
|
||||
pub use typst::foundations::Value;
|
||||
|
@ -35,4 +36,4 @@ pub use crate::lsp_typst_boundary::{
|
|||
};
|
||||
pub use crate::syntax::{classify_syntax, Decl, DefKind};
|
||||
pub(crate) use crate::ty::PathPreference;
|
||||
pub use crate::{SemanticRequest, StatefulRequest, VersionedDocument};
|
||||
pub use crate::{SemanticRequest, StatefulRequest};
|
||||
|
|
|
@ -34,11 +34,8 @@ pub struct PrepareRenameRequest {
|
|||
impl StatefulRequest for PrepareRenameRequest {
|
||||
type Response = PrepareRenameResponse;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.as_ref();
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let syntax = ctx.classify_for_decl(&source, self.position)?;
|
||||
if matches!(syntax.node().kind(), SyntaxKind::FieldAccess) {
|
||||
|
@ -48,7 +45,7 @@ impl StatefulRequest for PrepareRenameRequest {
|
|||
}
|
||||
|
||||
let origin_selection_range = ctx.to_lsp_range(syntax.node().range(), &source);
|
||||
let def = ctx.def_of_syntax(&source, doc.as_ref(), syntax.clone())?;
|
||||
let def = ctx.def_of_syntax(&source, doc, syntax.clone())?;
|
||||
|
||||
let (name, range) = prepare_renaming(ctx, &syntax, &def)?;
|
||||
|
||||
|
@ -136,15 +133,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn prepare() {
|
||||
snapshot_testing("rename", &|world, path| {
|
||||
let source = world.source_by_path(&path).unwrap();
|
||||
snapshot_testing("rename", &|ctx, path| {
|
||||
let source = ctx.source_by_path(&path).unwrap();
|
||||
|
||||
let request = PrepareRenameRequest {
|
||||
path: path.clone(),
|
||||
position: find_test_position(&source),
|
||||
};
|
||||
let snap = WorldComputeGraph::from_world(ctx.world.clone());
|
||||
|
||||
let result = request.request(world, None);
|
||||
let result = request.request(ctx, snap);
|
||||
assert_snapshot!(JsonRepr::new_redacted(result, &REDACT_LOC));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use typst::syntax::Span;
|
||||
|
||||
use crate::{
|
||||
|
@ -25,15 +26,12 @@ pub struct ReferencesRequest {
|
|||
impl StatefulRequest for ReferencesRequest {
|
||||
type Response = Vec<LspLocation>;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.as_ref();
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let syntax = ctx.classify_for_decl(&source, self.position)?;
|
||||
|
||||
let locations = find_references(ctx, &source, doc.as_ref(), syntax)?;
|
||||
let locations = find_references(ctx, &source, doc, syntax)?;
|
||||
|
||||
crate::log_debug_ct!("references: {locations:?}");
|
||||
Some(locations)
|
||||
|
@ -43,7 +41,7 @@ impl StatefulRequest for ReferencesRequest {
|
|||
pub(crate) fn find_references(
|
||||
ctx: &mut LocalContext,
|
||||
source: &Source,
|
||||
doc: Option<&VersionedDocument>,
|
||||
doc: Option<&TypstDocument>,
|
||||
syntax: SyntaxClass<'_>,
|
||||
) -> Option<Vec<LspLocation>> {
|
||||
let finding_label = match syntax {
|
||||
|
|
|
@ -36,15 +36,13 @@ pub struct RenameRequest {
|
|||
impl StatefulRequest for RenameRequest {
|
||||
type Response = WorkspaceEdit;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let doc = graph.snap.success_doc.as_ref();
|
||||
|
||||
let source = ctx.source_by_path(&self.path).ok()?;
|
||||
let syntax = ctx.classify_for_decl(&source, self.position)?;
|
||||
|
||||
let def = ctx.def_of_syntax(&source, doc.as_ref(), syntax.clone())?;
|
||||
let def = ctx.def_of_syntax(&source, doc, syntax.clone())?;
|
||||
|
||||
prepare_renaming(ctx, &syntax, &def)?;
|
||||
|
||||
|
@ -95,7 +93,7 @@ impl StatefulRequest for RenameRequest {
|
|||
})
|
||||
}
|
||||
_ => {
|
||||
let references = find_references(ctx, &source, doc.as_ref(), syntax)?;
|
||||
let references = find_references(ctx, &source, doc, syntax)?;
|
||||
|
||||
let mut edits = HashMap::new();
|
||||
|
||||
|
@ -321,16 +319,17 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test() {
|
||||
snapshot_testing("rename", &|world, path| {
|
||||
let source = world.source_by_path(&path).unwrap();
|
||||
snapshot_testing("rename", &|ctx, path| {
|
||||
let source = ctx.source_by_path(&path).unwrap();
|
||||
|
||||
let request = RenameRequest {
|
||||
path: path.clone(),
|
||||
position: find_test_position(&source),
|
||||
new_name: "new_name".to_string(),
|
||||
};
|
||||
let snap = WorldComputeGraph::from_world(ctx.world.clone());
|
||||
|
||||
let mut result = request.request(world, None);
|
||||
let mut result = request.request(ctx, snap);
|
||||
// sort the edits to make the snapshot stable
|
||||
if let Some(r) = result.as_mut().and_then(|r| r.changes.as_mut()) {
|
||||
for edits in r.values_mut() {
|
||||
|
|
|
@ -10,14 +10,12 @@ use std::{
|
|||
|
||||
use once_cell::sync::Lazy;
|
||||
use serde_json::{ser::PrettyFormatter, Serializer, Value};
|
||||
use tinymist_project::{CompileFontArgs, ExportTarget};
|
||||
use tinymist_project::{CompileFontArgs, ExportTarget, LspCompileSnapshot, LspComputeGraph};
|
||||
use tinymist_std::debug_loc::LspRange;
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use tinymist_world::package::PackageSpec;
|
||||
use tinymist_world::vfs::WorkspaceResolver;
|
||||
use tinymist_world::EntryState;
|
||||
use tinymist_world::TaskInputs;
|
||||
use tinymist_world::{EntryManager, EntryReader, ShadowApi};
|
||||
use tinymist_world::{EntryManager, EntryReader, EntryState, ShadowApi, TaskInputs};
|
||||
use typst::foundations::Bytes;
|
||||
use typst::syntax::ast::{self, AstNode};
|
||||
use typst::syntax::{LinkedNode, Source, SyntaxKind, VirtualPath};
|
||||
|
@ -26,12 +24,11 @@ pub use insta::assert_snapshot;
|
|||
pub use serde::Serialize;
|
||||
pub use serde_json::json;
|
||||
pub use tinymist_project::{LspUniverse, LspUniverseBuilder};
|
||||
pub use tinymist_world::WorldComputeGraph;
|
||||
use typst_shim::syntax::LinkedNodeExt;
|
||||
|
||||
use crate::syntax::find_module_level_docs;
|
||||
use crate::{
|
||||
analysis::Analysis, prelude::LocalContext, LspPosition, PositionEncoding, VersionedDocument,
|
||||
};
|
||||
use crate::{analysis::Analysis, prelude::LocalContext, LspPosition, PositionEncoding};
|
||||
use crate::{to_lsp_position, CompletionFeat, LspWorldExt};
|
||||
|
||||
pub fn snapshot_testing(name: &str, f: &impl Fn(&mut LocalContext, PathBuf)) {
|
||||
|
@ -122,13 +119,13 @@ pub fn get_test_properties(s: &str) -> HashMap<&'_ str, &'_ str> {
|
|||
pub fn compile_doc_for_test(
|
||||
ctx: &mut LocalContext,
|
||||
properties: &HashMap<&str, &str>,
|
||||
) -> Option<VersionedDocument> {
|
||||
) -> LspComputeGraph {
|
||||
let prev = ctx.world.entry_state();
|
||||
let next = match properties.get("compile")?.trim() {
|
||||
"true" => prev.clone(),
|
||||
"false" => return None,
|
||||
path if path.ends_with(".typ") => prev.select_in_workspace(Path::new(path)),
|
||||
v => panic!("invalid value for 'compile' property: {v}"),
|
||||
let next = match properties.get("compile").map(|s| s.trim()) {
|
||||
Some("true") => prev.clone(),
|
||||
None | Some("false") => return WorldComputeGraph::from_world(ctx.world.clone()),
|
||||
Some(path) if path.ends_with(".typ") => prev.select_in_workspace(Path::new(path)),
|
||||
v => panic!("invalid value for 'compile' property: {v:?}"),
|
||||
};
|
||||
|
||||
let mut world = Cow::Borrowed(&ctx.world);
|
||||
|
@ -138,14 +135,12 @@ pub fn compile_doc_for_test(
|
|||
..Default::default()
|
||||
}));
|
||||
}
|
||||
let mut world = world.into_owned();
|
||||
world.set_is_compiling(true);
|
||||
let mut snap = LspCompileSnapshot::from_world(world.into_owned());
|
||||
snap.world.set_is_compiling(true);
|
||||
|
||||
let doc = typst::compile(&world).output.unwrap();
|
||||
Some(VersionedDocument {
|
||||
version: 0,
|
||||
document: TypstDocument::Paged(Arc::new(doc)),
|
||||
})
|
||||
let doc = typst::compile(&snap.world).output.unwrap();
|
||||
snap.success_doc = Some(TypstDocument::Paged(Arc::new(doc)));
|
||||
WorldComputeGraph::new(snap)
|
||||
}
|
||||
|
||||
pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut LspUniverse, PathBuf) -> T) -> T {
|
||||
|
|
|
@ -15,11 +15,7 @@ pub struct WillRenameFilesRequest {
|
|||
impl StatefulRequest for WillRenameFilesRequest {
|
||||
type Response = WorkspaceEdit;
|
||||
|
||||
fn request(
|
||||
self,
|
||||
ctx: &mut LocalContext,
|
||||
_doc: Option<VersionedDocument>,
|
||||
) -> Option<Self::Response> {
|
||||
fn request(self, ctx: &mut LocalContext, _graph: LspComputeGraph) -> Option<Self::Response> {
|
||||
let mut edits: HashMap<Url, Vec<TextEdit>> = HashMap::new();
|
||||
|
||||
self.paths
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue