mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-25 05:22:52 +00:00
dev: reduce a bundle of ts usage in query crate (#72)
This commit is contained in:
parent
c6509325a8
commit
cc1f418423
25 changed files with 204 additions and 117 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -414,8 +414,10 @@ checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
"windows-targets 0.52.4",
|
"windows-targets 0.52.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3616,6 +3618,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
|
@ -3656,6 +3659,7 @@ version = "0.11.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"comemo",
|
"comemo",
|
||||||
|
"ecow",
|
||||||
"ena",
|
"ena",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"indexmap 2.2.5",
|
"indexmap 2.2.5",
|
||||||
|
|
@ -3666,6 +3670,7 @@ dependencies = [
|
||||||
"lsp-types",
|
"lsp-types",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"reflexo",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
|
||||||
14
Cargo.toml
14
Cargo.toml
|
|
@ -44,10 +44,23 @@ typst = "0.11.0"
|
||||||
typst-ide = "0.11.0"
|
typst-ide = "0.11.0"
|
||||||
typst-pdf = "0.11.0"
|
typst-pdf = "0.11.0"
|
||||||
typst-assets = { git = "https://github.com/typst/typst-assets", rev = "4d1211a" }
|
typst-assets = { git = "https://github.com/typst/typst-assets", rev = "4d1211a" }
|
||||||
|
reflexo = { version = "0.4.2-rc8", default-features = false, features = [
|
||||||
|
"flat-vector",
|
||||||
|
] }
|
||||||
typst-ts-core = { version = "0.4.2-rc8" }
|
typst-ts-core = { version = "0.4.2-rc8" }
|
||||||
typst-ts-compiler = { version = "0.4.2-rc8" }
|
typst-ts-compiler = { version = "0.4.2-rc8" }
|
||||||
typst-preview = { git = "https://github.com/Enter-tainer/typst-preview", rev = "18630ebda22339109ef675a885787f4fc8731ba8" }
|
typst-preview = { git = "https://github.com/Enter-tainer/typst-preview", rev = "18630ebda22339109ef675a885787f4fc8731ba8" }
|
||||||
|
|
||||||
|
# [features]
|
||||||
|
# rkyv = ["dep:rkyv", "rkyv/alloc", "rkyv/archive_le"]
|
||||||
|
# rkyv-validation = ["dep:rkyv", "rkyv/validation"]
|
||||||
|
# flat-vector = ["rkyv", "rkyv-validation"]
|
||||||
|
|
||||||
|
# __web = ["dep:wasm-bindgen", "dep:js-sys"]
|
||||||
|
# web = ["__web"]
|
||||||
|
# full = ["web", "flat-vector"]
|
||||||
|
# default = ["full"]
|
||||||
|
|
||||||
lsp-server = "0.7.6"
|
lsp-server = "0.7.6"
|
||||||
lsp-types = { version = "=0.95.0", features = ["proposed"] }
|
lsp-types = { version = "=0.95.0", features = ["proposed"] }
|
||||||
crossbeam-channel = "0.5.12"
|
crossbeam-channel = "0.5.12"
|
||||||
|
|
@ -113,6 +126,7 @@ typst-syntax = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "
|
||||||
# typst-syntax = { path = "../typst/crates/typst-syntax" }
|
# typst-syntax = { path = "../typst/crates/typst-syntax" }
|
||||||
|
|
||||||
typst-ts-svg-exporter = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-svg-exporter" }
|
typst-ts-svg-exporter = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-svg-exporter" }
|
||||||
|
reflexo = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "reflexo" }
|
||||||
typst-ts-core = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-core" }
|
typst-ts-core = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-core" }
|
||||||
typst-ts-compiler = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-compiler" }
|
typst-ts-compiler = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev = "2fc877de0a4bcd7a8f057933546a97348e9621c7", package = "typst-ts-compiler" }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,16 +28,18 @@ fxhash.workspace = true
|
||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
walkdir.workspace = true
|
walkdir.workspace = true
|
||||||
indexmap.workspace = true
|
indexmap.workspace = true
|
||||||
|
ecow.workspace = true
|
||||||
|
|
||||||
typst.workspace = true
|
typst.workspace = true
|
||||||
typst-ide.workspace = true
|
typst-ide.workspace = true
|
||||||
|
|
||||||
typst-ts-core = { version = "0.4.2-rc6", default-features = false, features = [
|
reflexo.workspace = true
|
||||||
|
typst-ts-compiler.workspace = true
|
||||||
|
typst-ts-core = { version = "0.4.2-rc8", default-features = false, features = [
|
||||||
"flat-vector",
|
"flat-vector",
|
||||||
"vector-bbox",
|
"vector-bbox",
|
||||||
"no-content-hint",
|
"no-content-hint",
|
||||||
] }
|
] }
|
||||||
typst-ts-compiler.workspace = true
|
|
||||||
|
|
||||||
lsp-types.workspace = true
|
lsp-types.workspace = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ pub use global::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod module_tests {
|
mod module_tests {
|
||||||
|
use ecow::EcoVec;
|
||||||
|
use reflexo::path::unix_slash;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use typst_ts_core::path::unix_slash;
|
|
||||||
use typst_ts_core::typst::prelude::EcoVec;
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::syntax::module::*;
|
use crate::syntax::module::*;
|
||||||
|
|
@ -18,7 +18,7 @@ mod module_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
snapshot_testing2("modules", &|ctx, _| {
|
snapshot_testing("modules", &|ctx, _| {
|
||||||
fn ids(ids: EcoVec<TypstFileId>) -> Vec<String> {
|
fn ids(ids: EcoVec<TypstFileId>) -> Vec<String> {
|
||||||
let mut ids: Vec<String> = ids
|
let mut ids: Vec<String> = ids
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -66,14 +66,14 @@ mod lexical_hierarchy_tests {
|
||||||
use def_use::DefUseSnapshot;
|
use def_use::DefUseSnapshot;
|
||||||
|
|
||||||
use crate::analysis::def_use;
|
use crate::analysis::def_use;
|
||||||
use crate::prelude::*;
|
// use crate::prelude::*;
|
||||||
use crate::syntax::lexical_hierarchy;
|
use crate::syntax::lexical_hierarchy;
|
||||||
use crate::tests::*;
|
use crate::tests::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scope() {
|
fn scope() {
|
||||||
snapshot_testing("lexical_hierarchy", &|world, path| {
|
snapshot_testing("lexical_hierarchy", &|ctx, path| {
|
||||||
let source = get_suitable_source_in_workspace(world, &path).unwrap();
|
let source = ctx.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let result = lexical_hierarchy::get_lexical_hierarchy(
|
let result = lexical_hierarchy::get_lexical_hierarchy(
|
||||||
source,
|
source,
|
||||||
|
|
@ -87,7 +87,7 @@ mod lexical_hierarchy_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_def_use() {
|
fn test_def_use() {
|
||||||
fn def_use(set: &str) {
|
fn def_use(set: &str) {
|
||||||
snapshot_testing2(set, &|ctx, path| {
|
snapshot_testing(set, &|ctx, path| {
|
||||||
let source = ctx.source_by_path(&path).unwrap();
|
let source = ctx.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let result = ctx.def_use(source);
|
let result = ctx.def_use(source);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use reflexo::path::unix_slash;
|
||||||
|
pub use reflexo::vector::ir::DefId;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use typst::syntax::FileId as TypstFileId;
|
||||||
use typst::syntax::Source;
|
use typst::syntax::Source;
|
||||||
use typst_ts_core::{path::unix_slash, TypstFileId};
|
|
||||||
|
|
||||||
use super::SearchCtx;
|
use super::SearchCtx;
|
||||||
use crate::syntax::{
|
use crate::syntax::{
|
||||||
|
|
@ -18,8 +20,6 @@ use crate::syntax::{
|
||||||
};
|
};
|
||||||
use crate::{adt::snapshot_map::SnapshotMap, syntax::LexicalModKind};
|
use crate::{adt::snapshot_map::SnapshotMap, syntax::LexicalModKind};
|
||||||
|
|
||||||
pub use typst_ts_core::vector::ir::DefId;
|
|
||||||
|
|
||||||
/// The type namespace of def-use relations
|
/// The type namespace of def-use relations
|
||||||
///
|
///
|
||||||
/// The symbols from different namespaces are not visible to each other.
|
/// The symbols from different namespaces are not visible to each other.
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
path::Path,
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
use reflexo::{cow_mut::CowMut, ImmutPath};
|
||||||
|
use typst::syntax::FileId as TypstFileId;
|
||||||
use typst::{
|
use typst::{
|
||||||
diag::{eco_format, FileError, FileResult},
|
diag::{eco_format, FileError, FileResult},
|
||||||
syntax::{Source, VirtualPath},
|
syntax::{Source, VirtualPath},
|
||||||
World,
|
World,
|
||||||
};
|
};
|
||||||
use typst_ts_compiler::{service::WorkspaceProvider, TypstSystemWorld};
|
use typst_ts_compiler::package::Registry;
|
||||||
use typst_ts_core::{cow_mut::CowMut, ImmutPath, TypstFileId};
|
use typst_ts_compiler::TypstSystemWorld;
|
||||||
|
// use typst_ts_compiler::TypstSystemWorld;
|
||||||
|
// use typst_ts_compiler::{service::WorkspaceProvider, TypstSystemWorld};
|
||||||
|
// use typst_ts_core::{cow_mut::CowMut, ImmutPath};
|
||||||
|
|
||||||
use super::{get_def_use_inner, DefUseInfo};
|
use super::{get_def_use_inner, DefUseInfo};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -57,10 +62,11 @@ pub struct Analysis {
|
||||||
/// changes.
|
/// changes.
|
||||||
pub root: ImmutPath,
|
pub root: ImmutPath,
|
||||||
/// The position encoding for the workspace.
|
/// The position encoding for the workspace.
|
||||||
position_encoding: PositionEncoding,
|
pub position_encoding: PositionEncoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cache for all level of analysis results of a module.
|
/// A cache for all level of analysis results of a module.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct AnalysisCaches {
|
pub struct AnalysisCaches {
|
||||||
modules: HashMap<TypstFileId, ModuleAnalysisCache>,
|
modules: HashMap<TypstFileId, ModuleAnalysisCache>,
|
||||||
root_files: OnceCell<Vec<TypstFileId>>,
|
root_files: OnceCell<Vec<TypstFileId>>,
|
||||||
|
|
@ -78,18 +84,11 @@ pub struct AnalysisContext<'a> {
|
||||||
|
|
||||||
impl<'w> AnalysisContext<'w> {
|
impl<'w> AnalysisContext<'w> {
|
||||||
/// Create a new analysis context.
|
/// Create a new analysis context.
|
||||||
pub fn new(world: &'w TypstSystemWorld, encoding: PositionEncoding) -> Self {
|
pub fn new(world: &'w TypstSystemWorld, a: Analysis) -> Self {
|
||||||
Self {
|
Self {
|
||||||
world,
|
world,
|
||||||
analysis: CowMut::Owned(Analysis {
|
analysis: CowMut::Owned(a),
|
||||||
root: world.workspace_root(),
|
caches: AnalysisCaches::default(),
|
||||||
position_encoding: encoding,
|
|
||||||
}),
|
|
||||||
caches: AnalysisCaches {
|
|
||||||
modules: HashMap::new(),
|
|
||||||
root_files: OnceCell::new(),
|
|
||||||
module_deps: OnceCell::new(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,6 +116,24 @@ impl<'w> AnalysisContext<'w> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve the real path for a file id.
|
||||||
|
pub fn path_for_id(&self, id: TypstFileId) -> Result<PathBuf, FileError> {
|
||||||
|
if id.vpath().as_rootless_path() == Path::new("-") {
|
||||||
|
return Ok(PathBuf::from("-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the root path relative to which the file path
|
||||||
|
// will be resolved.
|
||||||
|
let root = match id.package() {
|
||||||
|
Some(spec) => self.world.registry.resolve(spec)?,
|
||||||
|
None => self.analysis.root.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Join the path to the root. If it tries to escape, deny
|
||||||
|
// access. Note: It can still escape via symlinks.
|
||||||
|
id.vpath().resolve(&root).ok_or(FileError::AccessDenied)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the source of a file by file id.
|
/// Get the source of a file by file id.
|
||||||
pub fn source_by_id(&mut self, id: TypstFileId) -> FileResult<Source> {
|
pub fn source_by_id(&mut self, id: TypstFileId) -> FileResult<Source> {
|
||||||
self.get_mut(id);
|
self.get_mut(id);
|
||||||
|
|
@ -173,6 +190,10 @@ impl<'w> AnalysisContext<'w> {
|
||||||
lsp_to_typst::range(position, self.analysis.position_encoding, src)
|
lsp_to_typst::range(position, self.analysis.position_encoding, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_lsp_pos(&self, typst_offset: usize, src: &Source) -> LspPosition {
|
||||||
|
typst_to_lsp::offset_to_position(typst_offset, self.analysis.position_encoding, src)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_lsp_range(&self, position: TypstRange, src: &Source) -> LspRange {
|
pub fn to_lsp_range(&self, position: TypstRange, src: &Source) -> LspRange {
|
||||||
typst_to_lsp::range(position, src, self.analysis.position_encoding)
|
typst_to_lsp::range(position, src, self.analysis.position_encoding)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
//! Dynamic analysis of an expression or import statement.
|
//! Dynamic analysis of an expression or import statement.
|
||||||
|
|
||||||
use comemo::Track;
|
use comemo::Track;
|
||||||
|
use ecow::*;
|
||||||
use typst::engine::{Engine, Route};
|
use typst::engine::{Engine, Route};
|
||||||
use typst::eval::{Tracer, Vm};
|
use typst::eval::{Tracer, Vm};
|
||||||
use typst::foundations::{Context, Label, Scopes, Styles, Value};
|
use typst::foundations::{Context, Label, Scopes, Styles, Value};
|
||||||
|
|
@ -8,7 +9,6 @@ use typst::introspection::{Introspector, Locator};
|
||||||
use typst::model::{BibliographyElem, Document};
|
use typst::model::{BibliographyElem, Document};
|
||||||
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind};
|
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind};
|
||||||
use typst::World;
|
use typst::World;
|
||||||
use typst_ts_core::typst::prelude::*;
|
|
||||||
|
|
||||||
/// Try to determine a set of possible values for an expression.
|
/// Try to determine a set of possible values for an expression.
|
||||||
pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<(Value, Option<Styles>)> {
|
pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<(Value, Option<Styles>)> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::prelude::*;
|
use crate::{prelude::*, StatefulRequest};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CompletionRequest {
|
pub struct CompletionRequest {
|
||||||
|
|
@ -7,16 +7,17 @@ pub struct CompletionRequest {
|
||||||
pub explicit: bool,
|
pub explicit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompletionRequest {
|
impl StatefulRequest for CompletionRequest {
|
||||||
pub fn request(
|
type Response = CompletionResponse;
|
||||||
|
|
||||||
|
fn request(
|
||||||
self,
|
self,
|
||||||
world: &TypstSystemWorld,
|
ctx: &mut AnalysisContext,
|
||||||
doc: Option<VersionedDocument>,
|
doc: Option<VersionedDocument>,
|
||||||
position_encoding: PositionEncoding,
|
) -> Option<Self::Response> {
|
||||||
) -> Option<CompletionResponse> {
|
|
||||||
let doc = doc.as_ref().map(|doc| doc.document.as_ref());
|
let doc = doc.as_ref().map(|doc| doc.document.as_ref());
|
||||||
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
|
let source = ctx.source_by_path(&self.path).ok()?;
|
||||||
let cursor = lsp_to_typst::position(self.position, position_encoding, &source)?;
|
let cursor = ctx.to_typst_pos(self.position, &source)?;
|
||||||
|
|
||||||
// Please see <https://github.com/nvarner/typst-lsp/commit/2d66f26fb96ceb8e485f492e5b81e9db25c3e8ec>
|
// Please see <https://github.com/nvarner/typst-lsp/commit/2d66f26fb96ceb8e485f492e5b81e9db25c3e8ec>
|
||||||
//
|
//
|
||||||
|
|
@ -33,10 +34,10 @@ impl CompletionRequest {
|
||||||
// assume that the completion is not explicit.
|
// assume that the completion is not explicit.
|
||||||
let explicit = false;
|
let explicit = false;
|
||||||
|
|
||||||
let (offset, completions) = typst_ide::autocomplete(world, doc, &source, cursor, explicit)?;
|
let (offset, completions) =
|
||||||
|
typst_ide::autocomplete(ctx.world, doc, &source, cursor, explicit)?;
|
||||||
|
|
||||||
let lsp_start_position =
|
let lsp_start_position = ctx.to_lsp_pos(offset, &source);
|
||||||
typst_to_lsp::offset_to_position(offset, position_encoding, &source);
|
|
||||||
let replace_range = LspRange::new(lsp_start_position, self.position);
|
let replace_range = LspRange::new(lsp_start_position, self.position);
|
||||||
Some(typst_to_lsp::completions(&completions, replace_range).into())
|
Some(typst_to_lsp::completions(&completions, replace_range).into())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ fn diagnostic_related_information(
|
||||||
Ok(tracepoints)
|
Ok(tracepoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diagnostic_span_id(typst_diagnostic: &TypstDiagnostic) -> Option<(FileId, TypstSpan)> {
|
fn diagnostic_span_id(typst_diagnostic: &TypstDiagnostic) -> Option<(TypstFileId, TypstSpan)> {
|
||||||
iter::once(typst_diagnostic.span)
|
iter::once(typst_diagnostic.span)
|
||||||
.chain(typst_diagnostic.trace.iter().map(|trace| trace.span))
|
.chain(typst_diagnostic.trace.iter().map(|trace| trace.span))
|
||||||
.find_map(|span| Some((span.id()?, span)))
|
.find_map(|span| Some((span.id()?, span)))
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
snapshot_testing("document_symbols", &|world, path| {
|
snapshot_testing("document_symbols", &|ctx, path| {
|
||||||
let request = DocumentSymbolRequest { path: path.clone() };
|
let request = DocumentSymbolRequest { path: path.clone() };
|
||||||
|
|
||||||
let source = get_suitable_source_in_workspace(world, &path).unwrap();
|
let source = ctx.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let result = request.request(source, PositionEncoding::Utf16);
|
let result = request.request(source, PositionEncoding::Utf16);
|
||||||
assert_snapshot!(JsonRepr::new_redacted(result.unwrap(), &REDACT_LOC));
|
assert_snapshot!(JsonRepr::new_redacted(result.unwrap(), &REDACT_LOC));
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ mod tests {
|
||||||
line_folding_only: true,
|
line_folding_only: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let source = get_suitable_source_in_workspace(world, &path).unwrap();
|
let source = world.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let result = request.request(source, PositionEncoding::Utf16);
|
let result = request.request(source, PositionEncoding::Utf16);
|
||||||
assert_snapshot!(JsonRepr::new_pure(result.unwrap()));
|
assert_snapshot!(JsonRepr::new_pure(result.unwrap()));
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ impl SyntaxRequest for GotoDeclarationRequest {
|
||||||
let ref_id = source.id();
|
let ref_id = source.id();
|
||||||
let ref_source = &source;
|
let ref_source = &source;
|
||||||
|
|
||||||
let span_path = ctx.world.path_for_id(ref_id).ok()?;
|
let span_path = ctx.path_for_id(ref_id).ok()?;
|
||||||
let range = ctx.to_lsp_range(ref_range, ref_source);
|
let range = ctx.to_lsp_range(ref_range, ref_source);
|
||||||
|
|
||||||
let uri = Url::from_file_path(span_path).ok()?;
|
let uri = Url::from_file_path(span_path).ok()?;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::ops::Range;
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use typst::foundations::Value;
|
use typst::foundations::Value;
|
||||||
use typst_ts_core::TypstFileId;
|
use typst::syntax::FileId as TypstFileId;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
|
@ -53,7 +53,7 @@ impl SyntaxRequest for GotoDefinitionRequest {
|
||||||
|
|
||||||
let def = find_definition(ctx, source.clone(), deref_target)?;
|
let def = find_definition(ctx, source.clone(), deref_target)?;
|
||||||
|
|
||||||
let span_path = ctx.world.path_for_id(def.fid).ok()?;
|
let span_path = ctx.path_for_id(def.fid).ok()?;
|
||||||
let uri = Url::from_file_path(span_path).ok()?;
|
let uri = Url::from_file_path(span_path).ok()?;
|
||||||
|
|
||||||
let span_source = ctx.source_by_id(def.fid).ok()?;
|
let span_source = ctx.source_by_id(def.fid).ok()?;
|
||||||
|
|
@ -221,7 +221,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
snapshot_testing2("goto_definition", &|world, path| {
|
snapshot_testing("goto_definition", &|world, path| {
|
||||||
let source = world.source_by_path(&path).unwrap();
|
let source = world.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let request = GotoDefinitionRequest {
|
let request = GotoDefinitionRequest {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::prelude::*;
|
use crate::{prelude::*, StatefulRequest};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct HoverRequest {
|
pub struct HoverRequest {
|
||||||
|
|
@ -6,24 +6,25 @@ pub struct HoverRequest {
|
||||||
pub position: LspPosition,
|
pub position: LspPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HoverRequest {
|
impl StatefulRequest for HoverRequest {
|
||||||
pub fn request(
|
type Response = Hover;
|
||||||
|
|
||||||
|
fn request(
|
||||||
self,
|
self,
|
||||||
world: &TypstSystemWorld,
|
ctx: &mut AnalysisContext,
|
||||||
doc: Option<VersionedDocument>,
|
doc: Option<VersionedDocument>,
|
||||||
position_encoding: PositionEncoding,
|
) -> Option<Self::Response> {
|
||||||
) -> Option<Hover> {
|
|
||||||
let doc = doc.as_ref().map(|doc| doc.document.as_ref());
|
let doc = doc.as_ref().map(|doc| doc.document.as_ref());
|
||||||
|
|
||||||
let source = get_suitable_source_in_workspace(world, &self.path).ok()?;
|
let source = ctx.source_by_path(&self.path).ok()?;
|
||||||
let offset = lsp_to_typst::position(self.position, position_encoding, &source)?;
|
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
|
// the typst's cursor is 1-based, so we need to add 1 to the offset
|
||||||
let cursor = offset + 1;
|
let cursor = offset + 1;
|
||||||
|
|
||||||
let typst_tooltip = typst_ide::tooltip(world, doc, &source, cursor)?;
|
let typst_tooltip = typst_ide::tooltip(ctx.world, doc, &source, cursor)?;
|
||||||
|
|
||||||
let ast_node = LinkedNode::new(source.root()).leaf_at(cursor)?;
|
let ast_node = LinkedNode::new(source.root()).leaf_at(cursor)?;
|
||||||
let range = typst_to_lsp::range(ast_node.range(), &source, position_encoding);
|
let range = ctx.to_lsp_range(ast_node.range(), &source);
|
||||||
|
|
||||||
Some(Hover {
|
Some(Hover {
|
||||||
contents: typst_to_lsp::tooltip(&typst_tooltip),
|
contents: typst_to_lsp::tooltip(&typst_tooltip),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{borrow::Cow, ops::Range};
|
use std::{borrow::Cow, ops::Range};
|
||||||
|
|
||||||
|
use ecow::eco_vec;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use lsp_types::{InlayHintKind, InlayHintLabel};
|
use lsp_types::{InlayHintKind, InlayHintLabel};
|
||||||
use typst::{
|
use typst::{
|
||||||
|
|
@ -7,7 +8,6 @@ use typst::{
|
||||||
syntax::SyntaxNode,
|
syntax::SyntaxNode,
|
||||||
util::LazyHash,
|
util::LazyHash,
|
||||||
};
|
};
|
||||||
use typst_ts_core::typst::prelude::eco_vec;
|
|
||||||
|
|
||||||
use crate::{prelude::*, SyntaxRequest};
|
use crate::{prelude::*, SyntaxRequest};
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ impl SyntaxRequest for InlayHintRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inlay_hint(
|
fn inlay_hint(
|
||||||
world: &TypstSystemWorld,
|
world: &dyn World,
|
||||||
source: &Source,
|
source: &Source,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
encoding: PositionEncoding,
|
encoding: PositionEncoding,
|
||||||
|
|
@ -76,7 +76,7 @@ fn inlay_hint(
|
||||||
const SMART: InlayHintConfig = InlayHintConfig::smart();
|
const SMART: InlayHintConfig = InlayHintConfig::smart();
|
||||||
|
|
||||||
struct InlayHintWorker<'a> {
|
struct InlayHintWorker<'a> {
|
||||||
world: &'a TypstSystemWorld,
|
world: &'a dyn World,
|
||||||
source: &'a Source,
|
source: &'a Source,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
encoding: PositionEncoding,
|
encoding: PositionEncoding,
|
||||||
|
|
@ -661,7 +661,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smart() {
|
fn smart() {
|
||||||
snapshot_testing2("inlay_hints", &|ctx, path| {
|
snapshot_testing("inlay_hints", &|ctx, path| {
|
||||||
let source = ctx.source_by_path(&path).unwrap();
|
let source = ctx.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let request = InlayHintRequest {
|
let request = InlayHintRequest {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub(crate) mod diagnostics;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub use analysis::AnalysisContext;
|
pub use analysis::AnalysisContext;
|
||||||
use typst_ts_core::TypstDocument;
|
use typst::model::Document as TypstDocument;
|
||||||
|
|
||||||
pub use diagnostics::*;
|
pub use diagnostics::*;
|
||||||
pub(crate) mod code_lens;
|
pub(crate) mod code_lens;
|
||||||
|
|
@ -62,6 +62,16 @@ pub trait SyntaxRequest {
|
||||||
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response>;
|
fn request(self, ctx: &mut AnalysisContext) -> Option<Self::Response>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait StatefulRequest {
|
||||||
|
type Response;
|
||||||
|
|
||||||
|
fn request(
|
||||||
|
self,
|
||||||
|
ctx: &mut AnalysisContext,
|
||||||
|
v: Option<VersionedDocument>,
|
||||||
|
) -> Option<Self::Response>;
|
||||||
|
}
|
||||||
|
|
||||||
mod polymorphic {
|
mod polymorphic {
|
||||||
use super::prelude::*;
|
use super::prelude::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,18 @@ pub use lsp_types::{
|
||||||
SemanticTokensDelta, SemanticTokensFullDeltaResult, SemanticTokensResult, SignatureHelp,
|
SemanticTokensDelta, SemanticTokensFullDeltaResult, SemanticTokensResult, SignatureHelp,
|
||||||
SignatureInformation, SymbolInformation, Url, WorkspaceEdit,
|
SignatureInformation, SymbolInformation, Url, WorkspaceEdit,
|
||||||
};
|
};
|
||||||
|
pub use reflexo::vector::ir::DefId;
|
||||||
pub use serde_json::Value as JsonValue;
|
pub use serde_json::Value as JsonValue;
|
||||||
pub use typst::diag::{EcoString, FileError, FileResult, Tracepoint};
|
pub use typst::diag::{EcoString, FileError, FileResult, Tracepoint};
|
||||||
pub use typst::foundations::{Func, ParamInfo, Value};
|
pub use typst::foundations::{Func, ParamInfo, Value};
|
||||||
|
pub use typst::syntax::FileId as TypstFileId;
|
||||||
pub use typst::syntax::{
|
pub use typst::syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
FileId, LinkedNode, Source, Spanned, SyntaxKind, VirtualPath,
|
LinkedNode, Source, Spanned, SyntaxKind,
|
||||||
};
|
};
|
||||||
pub use typst::World;
|
pub use typst::World;
|
||||||
use typst_ts_compiler::service::WorkspaceProvider;
|
// use typst_ts_compiler::service::WorkspaceProvider;
|
||||||
pub use typst_ts_compiler::TypstSystemWorld;
|
pub use typst_ts_compiler::TypstSystemWorld;
|
||||||
pub use typst_ts_core::TypstFileId;
|
|
||||||
|
|
||||||
pub use crate::analysis::{analyze_expr, AnalysisContext};
|
pub use crate::analysis::{analyze_expr, AnalysisContext};
|
||||||
pub use crate::lsp_typst_boundary::{
|
pub use crate::lsp_typst_boundary::{
|
||||||
|
|
@ -33,11 +34,3 @@ pub use crate::lsp_typst_boundary::{
|
||||||
TypstDiagnostic, TypstSeverity, TypstSpan,
|
TypstDiagnostic, TypstSeverity, TypstSpan,
|
||||||
};
|
};
|
||||||
pub use crate::VersionedDocument;
|
pub use crate::VersionedDocument;
|
||||||
|
|
||||||
pub fn get_suitable_source_in_workspace(w: &TypstSystemWorld, p: &Path) -> FileResult<Source> {
|
|
||||||
// todo: source in packages
|
|
||||||
let relative_path = p
|
|
||||||
.strip_prefix(&w.workspace_root())
|
|
||||||
.map_err(|_| FileError::NotFound(p.to_owned()))?;
|
|
||||||
w.source(TypstFileId::new(None, VirtualPath::new(relative_path)))
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use typst_ts_core::vector::ir::DefId;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
|
@ -116,7 +115,7 @@ pub(crate) fn find_references_root(
|
||||||
position_encoding: PositionEncoding,
|
position_encoding: PositionEncoding,
|
||||||
) -> Option<Vec<LspLocation>> {
|
) -> Option<Vec<LspLocation>> {
|
||||||
let def_source = ctx.source_by_id(def_fid).ok()?;
|
let def_source = ctx.source_by_id(def_fid).ok()?;
|
||||||
let def_path = ctx.world.path_for_id(def_fid).ok()?;
|
let def_path = ctx.path_for_id(def_fid).ok()?;
|
||||||
let uri = Url::from_file_path(def_path).ok()?;
|
let uri = Url::from_file_path(def_path).ok()?;
|
||||||
|
|
||||||
// todo: reuse uri, range to location
|
// todo: reuse uri, range to location
|
||||||
|
|
@ -140,7 +139,7 @@ pub(crate) fn find_references_root(
|
||||||
let ref_source = ctx.ctx.source_by_id(ref_fid).ok()?;
|
let ref_source = ctx.ctx.source_by_id(ref_fid).ok()?;
|
||||||
let def_use = ctx.ctx.def_use(ref_source.clone())?;
|
let def_use = ctx.ctx.def_use(ref_source.clone())?;
|
||||||
|
|
||||||
let uri = ctx.ctx.world.path_for_id(ref_fid).ok()?;
|
let uri = ctx.ctx.path_for_id(ref_fid).ok()?;
|
||||||
let uri = Url::from_file_path(uri).ok()?;
|
let uri = Url::from_file_path(uri).ok()?;
|
||||||
|
|
||||||
let mut redefines = vec![];
|
let mut redefines = vec![];
|
||||||
|
|
@ -176,7 +175,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
// goto_definition
|
// goto_definition
|
||||||
snapshot_testing2("references", &|world, path| {
|
snapshot_testing("references", &|world, path| {
|
||||||
let source = world.source_by_path(&path).unwrap();
|
let source = world.source_by_path(&path).unwrap();
|
||||||
|
|
||||||
let request = ReferencesRequest {
|
let request = ReferencesRequest {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl SyntaxRequest for RenameRequest {
|
||||||
let def_loc = {
|
let def_loc = {
|
||||||
let def_source = ctx.source_by_id(lnk.fid).ok()?;
|
let def_source = ctx.source_by_id(lnk.fid).ok()?;
|
||||||
|
|
||||||
let span_path = ctx.world.path_for_id(lnk.fid).ok()?;
|
let span_path = ctx.path_for_id(lnk.fid).ok()?;
|
||||||
let uri = Url::from_file_path(span_path).ok()?;
|
let uri = Url::from_file_path(span_path).ok()?;
|
||||||
|
|
||||||
let Some(range) = lnk.name_range else {
|
let Some(range) = lnk.name_range else {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use typst::syntax::{ast, package::PackageManifest, LinkedNode, Source, SyntaxKind, VirtualPath};
|
use ecow::EcoVec;
|
||||||
use typst_ts_core::{package::PackageSpec, typst::prelude::EcoVec, TypstFileId};
|
use typst::syntax::{
|
||||||
|
ast,
|
||||||
|
package::{PackageManifest, PackageSpec},
|
||||||
|
FileId as TypstFileId, LinkedNode, Source, SyntaxKind, VirtualPath,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
|
@ -13,7 +17,7 @@ fn resolve_id_by_path(
|
||||||
if import_path.starts_with('@') {
|
if import_path.starts_with('@') {
|
||||||
let spec = import_path.parse::<PackageSpec>().ok()?;
|
let spec = import_path.parse::<PackageSpec>().ok()?;
|
||||||
// Evaluate the manifest.
|
// Evaluate the manifest.
|
||||||
let manifest_id = FileId::new(Some(spec.clone()), VirtualPath::new("typst.toml"));
|
let manifest_id = TypstFileId::new(Some(spec.clone()), VirtualPath::new("typst.toml"));
|
||||||
let bytes = world.file(manifest_id).ok()?;
|
let bytes = world.file(manifest_id).ok()?;
|
||||||
let string = std::str::from_utf8(&bytes).map_err(FileError::from).ok()?;
|
let string = std::str::from_utf8(&bytes).map_err(FileError::from).ok()?;
|
||||||
let manifest: PackageManifest = toml::from_str(string).ok()?;
|
let manifest: PackageManifest = toml::from_str(string).ok()?;
|
||||||
|
|
@ -80,7 +84,7 @@ pub fn find_imports(world: &dyn World, source: &Source) -> EcoVec<TypstFileId> {
|
||||||
struct ImportWorker<'a> {
|
struct ImportWorker<'a> {
|
||||||
world: &'a dyn World,
|
world: &'a dyn World,
|
||||||
current: TypstFileId,
|
current: TypstFileId,
|
||||||
imports: EcoVec<(FileId, LinkedNode<'a>)>,
|
imports: EcoVec<(TypstFileId, LinkedNode<'a>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ImportWorker<'a> {
|
impl<'a> ImportWorker<'a> {
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,19 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use ecow::{eco_vec, EcoVec};
|
||||||
use log::info;
|
use log::info;
|
||||||
use lsp_types::SymbolKind;
|
use lsp_types::SymbolKind;
|
||||||
|
use reflexo::error::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use typst::{
|
use typst::{
|
||||||
syntax::{
|
syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
|
package::PackageSpec,
|
||||||
LinkedNode, Source, SyntaxKind,
|
LinkedNode, Source, SyntaxKind,
|
||||||
},
|
},
|
||||||
util::LazyHash,
|
util::LazyHash,
|
||||||
};
|
};
|
||||||
use typst_ts_core::{
|
|
||||||
error::prelude::WithContext,
|
|
||||||
package::PackageSpec,
|
|
||||||
typst::prelude::{eco_vec, EcoVec},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::IdentRef;
|
use super::IdentRef;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{collections::HashMap, path::Path, sync::Once};
|
use std::{collections::HashMap, path::Path, sync::Once};
|
||||||
|
|
||||||
use typst::syntax::VirtualPath;
|
use ecow::EcoVec;
|
||||||
use typst_ts_core::{typst::prelude::EcoVec, TypstFileId};
|
use typst::syntax::{FileId as TypstFileId, VirtualPath};
|
||||||
|
|
||||||
use crate::prelude::AnalysisContext;
|
use crate::prelude::AnalysisContext;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,11 @@ use typst_ts_core::{config::CompileOpts, Bytes, TypstFileId};
|
||||||
pub use insta::assert_snapshot;
|
pub use insta::assert_snapshot;
|
||||||
pub use typst_ts_compiler::TypstSystemWorld;
|
pub use typst_ts_compiler::TypstSystemWorld;
|
||||||
|
|
||||||
use crate::{prelude::AnalysisContext, typst_to_lsp, LspPosition, PositionEncoding};
|
use crate::{
|
||||||
|
analysis::Analysis, prelude::AnalysisContext, typst_to_lsp, LspPosition, PositionEncoding,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn snapshot_testing(name: &str, f: &impl Fn(&mut TypstSystemWorld, PathBuf)) {
|
pub fn snapshot_testing(name: &str, f: &impl Fn(&mut AnalysisContext, PathBuf)) {
|
||||||
let mut settings = insta::Settings::new();
|
let mut settings = insta::Settings::new();
|
||||||
settings.set_prepend_module_to_snapshot(false);
|
settings.set_prepend_module_to_snapshot(false);
|
||||||
settings.set_snapshot_path(format!("fixtures/{name}/snaps"));
|
settings.set_snapshot_path(format!("fixtures/{name}/snaps"));
|
||||||
|
|
@ -31,29 +33,31 @@ pub fn snapshot_testing(name: &str, f: &impl Fn(&mut TypstSystemWorld, PathBuf))
|
||||||
insta::glob!(&glob_path, |path| {
|
insta::glob!(&glob_path, |path| {
|
||||||
let contents = std::fs::read_to_string(path).unwrap();
|
let contents = std::fs::read_to_string(path).unwrap();
|
||||||
|
|
||||||
run_with_sources(&contents, f);
|
run_with_sources(&contents, |w: &mut TypstSystemWorld, p| {
|
||||||
|
let paths = w
|
||||||
|
.shadow_paths()
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| {
|
||||||
|
TypstFileId::new(
|
||||||
|
None,
|
||||||
|
VirtualPath::new(p.strip_prefix(w.workspace_root()).unwrap()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut ctx = AnalysisContext::new(
|
||||||
|
w,
|
||||||
|
Analysis {
|
||||||
|
root: w.workspace_root(),
|
||||||
|
position_encoding: PositionEncoding::Utf16,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
ctx.test_files(|| paths);
|
||||||
|
f(&mut ctx, p);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapshot_testing2(name: &str, f: &impl Fn(&mut AnalysisContext, PathBuf)) {
|
|
||||||
snapshot_testing(name, &|w, p| {
|
|
||||||
let paths = w
|
|
||||||
.shadow_paths()
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| {
|
|
||||||
TypstFileId::new(
|
|
||||||
None,
|
|
||||||
VirtualPath::new(p.strip_prefix(w.workspace_root()).unwrap()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let mut ctx = AnalysisContext::new(w, PositionEncoding::Utf16);
|
|
||||||
ctx.test_files(|| paths);
|
|
||||||
f(&mut ctx, p);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut TypstSystemWorld, PathBuf) -> T) -> T {
|
pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut TypstSystemWorld, PathBuf) -> T) -> T {
|
||||||
let root = if cfg!(windows) {
|
let root = if cfg!(windows) {
|
||||||
PathBuf::from("C:\\")
|
PathBuf::from("C:\\")
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ lsp-server.workspace = true
|
||||||
crossbeam-channel.workspace = true
|
crossbeam-channel.workspace = true
|
||||||
lsp-types.workspace = true
|
lsp-types.workspace = true
|
||||||
dhat = { version = "0.3.3", optional = true }
|
dhat = { version = "0.3.3", optional = true }
|
||||||
|
chrono = { version = "0.4" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["cli", "preview"]
|
default = ["cli", "preview"]
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@ use log::{debug, error, info, trace, warn};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use tinymist_query::{
|
use tinymist_query::{
|
||||||
analysis::AnalysisContext, CompilerQueryRequest, CompilerQueryResponse, DiagnosticsMap,
|
analysis::{Analysis, AnalysisContext},
|
||||||
FoldRequestFeature, OnExportRequest, OnSaveExportRequest, PositionEncoding, SyntaxRequest,
|
CompilerQueryRequest, CompilerQueryResponse, DiagnosticsMap, FoldRequestFeature,
|
||||||
|
OnExportRequest, OnSaveExportRequest, PositionEncoding, StatefulRequest, SyntaxRequest,
|
||||||
VersionedDocument,
|
VersionedDocument,
|
||||||
};
|
};
|
||||||
use tokio::sync::{broadcast, mpsc, oneshot, watch};
|
use tokio::sync::{broadcast, mpsc, oneshot, watch};
|
||||||
|
|
@ -204,8 +205,7 @@ impl<'a> fmt::Debug for ShowOpts<'a> {
|
||||||
|
|
||||||
macro_rules! query_state {
|
macro_rules! query_state {
|
||||||
($self:ident, $method:ident, $req:expr) => {{
|
($self:ident, $method:ident, $req:expr) => {{
|
||||||
let enc = $self.position_encoding;
|
let res = $self.steal_state(move |w, doc| $req.request(w, doc));
|
||||||
let res = $self.steal_state(move |w, doc| $req.request(w, doc, enc));
|
|
||||||
res.map(CompilerQueryResponse::$method)
|
res.map(CompilerQueryResponse::$method)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
@ -664,11 +664,39 @@ impl CompileActor {
|
||||||
|
|
||||||
fn steal_state<T: Send + Sync + 'static>(
|
fn steal_state<T: Send + Sync + 'static>(
|
||||||
&self,
|
&self,
|
||||||
f: impl FnOnce(&TypstSystemWorld, Option<VersionedDocument>) -> T + Send + Sync + 'static,
|
f: impl FnOnce(&mut AnalysisContext, Option<VersionedDocument>) -> T + Send + Sync + 'static,
|
||||||
) -> anyhow::Result<T> {
|
) -> anyhow::Result<T> {
|
||||||
let fut = self.steal(move |compiler| f(compiler.compiler.world(), compiler.success_doc()));
|
let enc = self.position_encoding;
|
||||||
|
|
||||||
Ok(fut?)
|
self.steal(move |compiler| {
|
||||||
|
// todo: record analysis
|
||||||
|
let doc = compiler.success_doc();
|
||||||
|
let w = compiler.compiler.world_mut();
|
||||||
|
|
||||||
|
let Some(main) = w.main else {
|
||||||
|
log::error!("TypstActor: main file is not set");
|
||||||
|
return Err(anyhow!("main file is not set"));
|
||||||
|
};
|
||||||
|
w.source(main).map_err(|err| {
|
||||||
|
log::info!("TypstActor: failed to prepare main file: {:?}", err);
|
||||||
|
anyhow!("failed to get source: {err}")
|
||||||
|
})?;
|
||||||
|
w.prepare_env(&mut Default::default()).map_err(|err| {
|
||||||
|
log::error!("TypstActor: failed to prepare env: {:?}", err);
|
||||||
|
anyhow!("failed to prepare env")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(f(
|
||||||
|
&mut AnalysisContext::new(
|
||||||
|
w,
|
||||||
|
Analysis {
|
||||||
|
root: w.root.clone(),
|
||||||
|
position_encoding: enc,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
doc,
|
||||||
|
))
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
|
|
||||||
fn steal_world<T: Send + Sync + 'static>(
|
fn steal_world<T: Send + Sync + 'static>(
|
||||||
|
|
@ -694,7 +722,13 @@ impl CompileActor {
|
||||||
anyhow!("failed to prepare env")
|
anyhow!("failed to prepare env")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(f(&mut AnalysisContext::new(compiler.compiler.world(), enc)))
|
Ok(f(&mut AnalysisContext::new(
|
||||||
|
w,
|
||||||
|
Analysis {
|
||||||
|
root: w.root.clone(),
|
||||||
|
position_encoding: enc,
|
||||||
|
},
|
||||||
|
)))
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue