refactor: make state query functions closer (#102)

This commit is contained in:
Myriad-Dreamin 2024-03-26 11:40:05 +08:00 committed by GitHub
parent 413c2e8deb
commit 63d332f8d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 56 deletions

View file

@ -35,9 +35,7 @@ use log::{error, info, trace};
use parking_lot::Mutex;
use tinymist_query::{
analysis::{Analysis, AnalysisContext, AnaylsisResources},
CompilerQueryRequest, CompilerQueryResponse, DiagnosticsMap, ExportKind, FoldRequestFeature,
OnExportRequest, OnSaveExportRequest, PositionEncoding, SemanticRequest, StatefulRequest,
VersionedDocument,
DiagnosticsMap, ExportKind, PositionEncoding, VersionedDocument,
};
use tokio::sync::{broadcast, mpsc, oneshot, watch};
use typst::{
@ -386,52 +384,7 @@ impl CompileClientActor {
}
impl CompileClientActor {
pub fn query(&self, query: CompilerQueryRequest) -> anyhow::Result<CompilerQueryResponse> {
use CompilerQueryRequest::*;
assert!(query.fold_feature() != FoldRequestFeature::ContextFreeUnique);
macro_rules! query_state {
($self:ident, $method:ident, $req:expr) => {{
let res = $self.steal_state(move |w, doc| $req.request(w, doc));
res.map(CompilerQueryResponse::$method)
}};
}
macro_rules! query_world {
($self:ident, $method:ident, $req:expr) => {{
let res = $self.steal_world(move |w| $req.request(w));
res.map(CompilerQueryResponse::$method)
}};
}
match query {
CompilerQueryRequest::OnExport(OnExportRequest { kind, path }) => {
Ok(CompilerQueryResponse::OnExport(self.on_export(kind, path)?))
}
CompilerQueryRequest::OnSaveExport(OnSaveExportRequest { path }) => {
self.on_save_export(path)?;
Ok(CompilerQueryResponse::OnSaveExport(()))
}
Hover(req) => query_state!(self, Hover, req),
GotoDefinition(req) => query_world!(self, GotoDefinition, req),
GotoDeclaration(req) => query_world!(self, GotoDeclaration, req),
References(req) => query_world!(self, References, req),
InlayHint(req) => query_world!(self, InlayHint, req),
CodeLens(req) => query_world!(self, CodeLens, req),
Completion(req) => query_state!(self, Completion, req),
SignatureHelp(req) => query_world!(self, SignatureHelp, req),
Rename(req) => query_world!(self, Rename, req),
PrepareRename(req) => query_world!(self, PrepareRename, req),
Symbol(req) => query_world!(self, Symbol, req),
FoldingRange(..)
| SelectionRange(..)
| SemanticTokensDelta(..)
| DocumentSymbol(..)
| SemanticTokensFull(..) => unreachable!(),
}
}
fn on_export(&self, kind: ExportKind, path: PathBuf) -> anyhow::Result<Option<PathBuf>> {
pub fn on_export(&self, kind: ExportKind, path: PathBuf) -> anyhow::Result<Option<PathBuf>> {
// todo: we currently doesn't respect the path argument...
info!("CompileActor: on export: {}", path.display());
@ -452,14 +405,14 @@ impl CompileClientActor {
Ok(res)
}
fn on_save_export(&self, path: PathBuf) -> anyhow::Result<()> {
pub fn on_save_export(&self, path: PathBuf) -> anyhow::Result<()> {
info!("CompileActor: on save export: {}", path.display());
let _ = self.render_tx.send(RenderActorRequest::OnSaved(path));
Ok(())
}
fn steal_state<T: Send + Sync + 'static>(
pub fn steal_state<T: Send + Sync + 'static>(
&self,
f: impl FnOnce(&mut AnalysisContext, Option<VersionedDocument>) -> T + Send + Sync + 'static,
) -> anyhow::Result<T> {
@ -470,7 +423,7 @@ impl CompileClientActor {
})?
}
fn steal_world<T: Send + Sync + 'static>(
pub fn steal_world<T: Send + Sync + 'static>(
&self,
f: impl FnOnce(&mut AnalysisContext) -> T + Send + Sync + 'static,
) -> anyhow::Result<T> {

View file

@ -6,7 +6,8 @@ use ::typst::{diag::FileResult, syntax::Source};
use anyhow::anyhow;
use lsp_types::TextDocumentContentChangeEvent;
use tinymist_query::{
lsp_to_typst, CompilerQueryRequest, CompilerQueryResponse, PositionEncoding, SyntaxRequest,
lsp_to_typst, CompilerQueryRequest, CompilerQueryResponse, FoldRequestFeature, OnExportRequest,
OnSaveExportRequest, PositionEncoding, SemanticRequest, StatefulRequest, SyntaxRequest,
};
use typst_ts_compiler::{
vfs::notify::{FileChangeSet, MemoryEvent},
@ -14,7 +15,7 @@ use typst_ts_compiler::{
};
use typst_ts_core::{error::prelude::*, Bytes, Error, ImmutPath};
use crate::TypstLanguageServer;
use crate::{actor::typ_client::CompileClientActor, TypstLanguageServer};
#[derive(Debug, Clone)]
pub struct MemoryFileMeta {
@ -184,6 +185,20 @@ macro_rules! query_tokens_cache {
}};
}
macro_rules! query_state {
($self:ident, $method:ident, $req:expr) => {{
let res = $self.steal_state(move |w, doc| $req.request(w, doc));
res.map(CompilerQueryResponse::$method)
}};
}
macro_rules! query_world {
($self:ident, $method:ident, $req:expr) => {{
let res = $self.steal_world(move |w| $req.request(w));
res.map(CompilerQueryResponse::$method)
}};
}
impl TypstLanguageServer {
pub fn query(&self, query: CompilerQueryRequest) -> anyhow::Result<CompilerQueryResponse> {
use CompilerQueryRequest::*;
@ -196,16 +211,50 @@ impl TypstLanguageServer {
DocumentSymbol(req) => query_source!(self, DocumentSymbol, req),
_ => {
match self.main.as_ref() {
Some(main) if self.pinning => main.query(query),
Some(main) if self.pinning => Self::query_on(main, query),
Some(..) | None => {
// todo: race condition, we need atomic primary query
if let Some(path) = query.associated_path() {
self.primary().change_entry(Some(path.into()))?;
}
self.primary().query(query)
Self::query_on(self.primary(), query)
}
}
}
}
}
fn query_on(
client: &CompileClientActor,
query: CompilerQueryRequest,
) -> anyhow::Result<CompilerQueryResponse> {
use CompilerQueryRequest::*;
assert!(query.fold_feature() != FoldRequestFeature::ContextFreeUnique);
match query {
CompilerQueryRequest::OnExport(OnExportRequest { kind, path }) => Ok(
CompilerQueryResponse::OnExport(client.on_export(kind, path)?),
),
CompilerQueryRequest::OnSaveExport(OnSaveExportRequest { path }) => {
client.on_save_export(path)?;
Ok(CompilerQueryResponse::OnSaveExport(()))
}
Hover(req) => query_state!(client, Hover, req),
GotoDefinition(req) => query_world!(client, GotoDefinition, req),
GotoDeclaration(req) => query_world!(client, GotoDeclaration, req),
References(req) => query_world!(client, References, req),
InlayHint(req) => query_world!(client, InlayHint, req),
CodeLens(req) => query_world!(client, CodeLens, req),
Completion(req) => query_state!(client, Completion, req),
SignatureHelp(req) => query_world!(client, SignatureHelp, req),
Rename(req) => query_world!(client, Rename, req),
PrepareRename(req) => query_world!(client, PrepareRename, req),
Symbol(req) => query_world!(client, Symbol, req),
FoldingRange(..)
| SelectionRange(..)
| SemanticTokensDelta(..)
| DocumentSymbol(..)
| SemanticTokensFull(..) => unreachable!(),
}
}
}