summaryrefslogtreecommitdiff
path: root/support/texlab/src/feature.rs
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
committerNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
commitf1261b349e875b842745b63258c3e338cb1fe3bf (patch)
treeb5d402b3e80818cde2c079a42249f3dcb9732247 /support/texlab/src/feature.rs
parent58aa1ac09b1d9e4769d0a0661cf12e2b2db41b14 (diff)
CTAN sync 202105230300
Diffstat (limited to 'support/texlab/src/feature.rs')
-rw-r--r--support/texlab/src/feature.rs405
1 files changed, 0 insertions, 405 deletions
diff --git a/support/texlab/src/feature.rs b/support/texlab/src/feature.rs
deleted file mode 100644
index 2b32b64188..0000000000
--- a/support/texlab/src/feature.rs
+++ /dev/null
@@ -1,405 +0,0 @@
-use crate::{
- components::{Component, COMPONENT_DATABASE},
- protocol::*,
- tex::{Distribution, Language, UnknownDistribution},
- workspace::{Document, DocumentContent, DocumentParams, Snapshot},
-};
-use async_trait::async_trait;
-use itertools::Itertools;
-use std::{
- env,
- path::{Path, PathBuf},
- sync::Arc,
-};
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct DocumentView {
- pub snapshot: Arc<Snapshot>,
- pub current: Arc<Document>,
- pub related: Vec<Arc<Document>>,
-}
-
-impl DocumentView {
- pub fn analyze(
- snapshot: Arc<Snapshot>,
- current: Arc<Document>,
- options: &Options,
- current_dir: &Path,
- ) -> Self {
- let related = snapshot.relations(&current.uri, options, current_dir);
- Self {
- snapshot,
- current,
- related,
- }
- }
-
- pub fn components(&self) -> Vec<&'static Component> {
- let mut start_components = vec![COMPONENT_DATABASE.kernel()];
- for doc in &self.related {
- if let DocumentContent::Latex(table) = &doc.content {
- table
- .components
- .iter()
- .flat_map(|file| COMPONENT_DATABASE.find(file))
- .for_each(|component| start_components.push(component))
- }
- }
-
- let mut all_components = Vec::new();
- for component in start_components {
- all_components.push(component);
- component
- .references
- .iter()
- .flat_map(|file| COMPONENT_DATABASE.find(&file))
- .for_each(|component| all_components.push(component))
- }
-
- all_components
- .into_iter()
- .unique_by(|component| &component.file_names)
- .collect()
- }
-}
-
-#[derive(Clone)]
-pub struct FeatureRequest<P> {
- pub params: P,
- pub view: DocumentView,
- pub distro: Arc<dyn Distribution>,
- pub client_capabilities: Arc<ClientCapabilities>,
- pub options: Options,
- pub current_dir: Arc<PathBuf>,
-}
-
-impl<P> FeatureRequest<P> {
- pub fn snapshot(&self) -> &Snapshot {
- &self.view.snapshot
- }
-
- pub fn current(&self) -> &Document {
- &self.view.current
- }
-
- pub fn related(&self) -> &[Arc<Document>] {
- &self.view.related
- }
-}
-
-#[async_trait]
-pub trait FeatureProvider {
- type Params;
- type Output;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output;
-}
-
-type ListProvider<P, O> = Box<dyn FeatureProvider<Params = P, Output = Vec<O>> + Send + Sync>;
-
-#[derive(Default)]
-pub struct ConcatProvider<P, O> {
- providers: Vec<ListProvider<P, O>>,
-}
-
-impl<P, O> ConcatProvider<P, O> {
- pub fn new(providers: Vec<ListProvider<P, O>>) -> Self {
- Self { providers }
- }
-}
-
-#[async_trait]
-impl<P, O> FeatureProvider for ConcatProvider<P, O>
-where
- P: Send + Sync,
- O: Send + Sync,
-{
- type Params = P;
- type Output = Vec<O>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<P>) -> Vec<O> {
- let mut items = Vec::new();
- for provider in &self.providers {
- items.append(&mut provider.execute(req).await);
- }
- items
- }
-}
-
-type OptionProvider<P, O> = Box<dyn FeatureProvider<Params = P, Output = Option<O>> + Send + Sync>;
-
-#[derive(Default)]
-pub struct ChoiceProvider<P, O> {
- providers: Vec<OptionProvider<P, O>>,
-}
-
-impl<P, O> ChoiceProvider<P, O> {
- pub fn new(providers: Vec<OptionProvider<P, O>>) -> Self {
- Self { providers }
- }
-}
-
-#[async_trait]
-impl<P, O> FeatureProvider for ChoiceProvider<P, O>
-where
- P: Send + Sync,
- O: Send + Sync,
-{
- type Params = P;
- type Output = Option<O>;
-
- async fn execute<'a>(&'a self, req: &'a FeatureRequest<P>) -> Option<O> {
- for provider in &self.providers {
- let item = provider.execute(req).await;
- if item.is_some() {
- return item;
- }
- }
- None
- }
-}
-
-#[derive(Debug)]
-pub struct FeatureTester {
- main: String,
- files: Vec<(String, String)>,
- distro: Arc<dyn Distribution>,
- position: Position,
- new_name: String,
- include_declaration: bool,
- client_capabilities: Arc<ClientCapabilities>,
- current_dir: Arc<PathBuf>,
- root_dir: Option<PathBuf>,
- output_dir: Option<PathBuf>,
-}
-
-impl Default for FeatureTester {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl FeatureTester {
- pub fn new() -> Self {
- Self {
- main: String::new(),
- files: Vec::new(),
- distro: Arc::new(UnknownDistribution::default()),
- position: Position::default(),
- new_name: String::new(),
- include_declaration: false,
- client_capabilities: Arc::default(),
- current_dir: Arc::new(env::temp_dir()),
- root_dir: None,
- output_dir: None,
- }
- }
-
- pub fn main<S: Into<String>>(&mut self, name: S) -> &mut Self {
- self.main = name.into();
- self
- }
-
- pub fn file<S, T>(&mut self, name: S, text: T) -> &mut Self
- where
- S: Into<String>,
- T: Into<String>,
- {
- self.files.push((name.into(), text.into()));
- self
- }
-
- pub fn position(&mut self, line: u64, character: u64) -> &mut Self {
- self.position = Position::new(line, character);
- self
- }
-
- pub fn new_name<S: Into<String>>(&mut self, value: S) -> &mut Self {
- self.new_name = value.into();
- self
- }
-
- pub fn include_declaration(&mut self) -> &mut Self {
- self.include_declaration = true;
- self
- }
-
- pub fn root_directory<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.root_dir = Some(path.into());
- self
- }
-
- pub fn output_directory<P: Into<PathBuf>>(&mut self, path: P) -> &mut Self {
- self.output_dir = Some(path.into());
- self
- }
-
- pub fn uri(name: &str) -> Uri {
- let path = env::temp_dir().join(name);
- Uri::from_file_path(path).unwrap()
- }
-
- fn identifier(&self) -> TextDocumentIdentifier {
- let uri = Self::uri(&self.main);
- TextDocumentIdentifier::new(uri.into())
- }
-
- fn options(&self) -> Options {
- Options {
- latex: Some(LatexOptions {
- build: Some(LatexBuildOptions {
- output_directory: self.output_dir.clone(),
- ..LatexBuildOptions::default()
- }),
- root_directory: self.root_dir.clone(),
- ..LatexOptions::default()
- }),
- ..Options::default()
- }
- }
-
- async fn view(&self) -> DocumentView {
- let mut snapshot = Snapshot::new();
- let resolver = self.distro.resolver().await;
- let options = self.options();
- for (name, text) in &self.files {
- let uri = Self::uri(name);
- let path = uri.to_file_path().unwrap();
- let language = path
- .extension()
- .and_then(|ext| ext.to_str())
- .and_then(Language::by_extension)
- .unwrap();
- let doc = Document::open(DocumentParams {
- uri,
- text: text.trim().into(),
- language,
- resolver: &resolver,
- options: &options,
- current_dir: &self.current_dir,
- });
- snapshot.push(doc);
- }
- let current = snapshot.find(&Self::uri(&self.main)).unwrap();
- DocumentView::analyze(Arc::new(snapshot), current, &options, &self.current_dir)
- }
-
- async fn request<P>(&self, params: P) -> FeatureRequest<P> {
- FeatureRequest {
- params,
- view: self.view().await,
- client_capabilities: Arc::clone(&self.client_capabilities),
- distro: self.distro.clone(),
- options: self.options(),
- current_dir: Arc::clone(&self.current_dir),
- }
- }
-
- pub async fn test_position<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = TextDocumentPositionParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = TextDocumentPositionParams::new(text_document, self.position);
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_completion<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = CompletionParams, Output = O>,
- {
- let req = self.test_completion_request().await;
- provider.execute(&req).await
- }
-
- pub async fn test_completion_request(&self) -> FeatureRequest<CompletionParams> {
- let params = CompletionParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- context: None,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- self.request(params).await
- }
-
- pub async fn test_folding<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = FoldingRangeParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = FoldingRangeParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_link<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = DocumentLinkParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = DocumentLinkParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_reference<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = ReferenceParams, Output = O>,
- {
- let params = ReferenceParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- context: ReferenceContext {
- include_declaration: self.include_declaration,
- },
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_rename<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = RenameParams, Output = O>,
- {
- let params = RenameParams {
- text_document_position: TextDocumentPositionParams::new(
- self.identifier(),
- self.position,
- ),
- new_name: self.new_name.clone(),
- work_done_progress_params: WorkDoneProgressParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-
- pub async fn test_symbol<F, O>(&self, provider: F) -> O
- where
- F: FeatureProvider<Params = DocumentSymbolParams, Output = O>,
- {
- let text_document = self.identifier();
- let params = DocumentSymbolParams {
- text_document,
- work_done_progress_params: WorkDoneProgressParams::default(),
- partial_result_params: PartialResultParams::default(),
- };
- let req = self.request(params).await;
- provider.execute(&req).await
- }
-}