173 lines
4.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::{fs, future};
use std::path::PathBuf;
use std::sync::Arc;
use log::info;
use notification::Notification;
use ropey::Rope;
use serde::{Deserialize, Serialize};
use tower_lsp::jsonrpc::Result;
use tower_lsp::lsp_types::*;
use crate::core::fast_hdlparam::FastHdlparam;
use crate::core::sv_parser::make_fast_from_syntaxtree;
use crate::utils::*;
use crate::server::{Backend, GLOBAL_BACKEND};
use crate::sources::recovery_sv_parse;
#[derive(Clone)]
pub struct CustomRequest;
impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (), Result<i32>> for CustomRequest {
type Future = future::Ready<Result<i32>>;
fn invoke(&self, _server: &'a Arc<Backend>, _params: ()) -> Self::Future {
future::ready(custom_request())
}
}
pub fn custom_request() -> Result<i32> {
Ok(123)
}
#[derive(Deserialize, Serialize, Debug)]
pub struct CustomParamRequestParams {
param: String,
}
#[derive(Clone)]
pub struct CustomParamRequest;
impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (CustomParamRequestParams, ), Result<i32>> for CustomParamRequest {
type Future = future::Ready<Result<i32>>;
fn invoke(&self, _server: &'a Arc<Backend>, _params: (CustomParamRequestParams, )) -> Self::Future {
future::ready(custom_param_request(_params.0.param))
}
}
pub fn custom_param_request(param: String) -> Result<i32> {
info!("receive param: {:?}", param);
Ok(123)
}
#[derive(Deserialize, Serialize, Debug)]
pub struct DoFastApiRequestParams {
path: String,
}
#[derive(Clone)]
pub struct DoFastApi;
impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (DoFastApiRequestParams, ), Result<FastHdlparam>> for DoFastApi {
type Future = future::Ready<Result<FastHdlparam>>;
fn invoke(&self, _server: &'a Arc<Backend>, _params: (DoFastApiRequestParams, )) -> Self::Future {
let request_param = _params.0;
let path = request_param.path;
let hdlparam = do_fast(path, _server);
future::ready(hdlparam)
}
}
fn make_textdocumenitem_from_path(path_buf: &PathBuf) -> Option<TextDocumentItem> {
if let Ok(url) = Url::from_file_path(path_buf) {
if let Ok(text) = fs::read_to_string(path_buf) {
let language_id = get_language_id_by_uri(&url);
return Some(TextDocumentItem::new(url, language_id, -1, text));
}
}
None
}
/// 前端交互接口: do_fast输入文件路径计算出对应的 fast 结构
pub fn do_fast<'a>(path: String, _server: &Arc<Backend>) -> Result<FastHdlparam> {
info!("parse fast {}", path);
let path_buf = PathBuf::from(&path);
let doc = match make_textdocumenitem_from_path(&path_buf) {
Some(doc) => doc,
None => {
let api_error = tower_lsp::jsonrpc::Error {
code: tower_lsp::jsonrpc::ErrorCode::InvalidParams,
message: std::borrow::Cow::Owned(format!("cannot make doc from path : {path}")),
data: None
};
return Err(api_error);
}
};
let uri = doc.uri;
let text = Rope::from(doc.text);
// fast 解析不需要 include
let includes: Vec<PathBuf> = Vec::new();
let parse_result = recovery_sv_parse(
&text,
&uri,
&None,
&includes
);
if let Some(syntax_tree) = parse_result {
if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
let hdl_param = _server.server.srcs.hdl_param.clone();
hdl_param.update_fast(path.to_string(), fast.clone());
return Ok(fast);
}
}
let api_error = tower_lsp::jsonrpc::Error {
code: tower_lsp::jsonrpc::ErrorCode::ParseError,
message: std::borrow::Cow::Owned("message".to_string()),
data: None
};
Err(api_error)
}
// 下面是服务端发送给客户端的
#[derive(Serialize, Deserialize)]
pub struct StringNotification {
pub content: String
}
impl Notification for StringNotification {
const METHOD: &'static str = "update/string";
type Params = Self;
}
#[derive(Serialize, Deserialize)]
pub struct UpdateFastNotification {
pub fast: FastHdlparam,
pub path: String
}
impl Notification for UpdateFastNotification {
const METHOD: &'static str = "update/fast";
type Params = Self;
}
#[allow(unused)]
pub async fn update_fast_to_client(fast: FastHdlparam, path: &PathBuf) {
// info!("send fast to foreend {:?}", fast);
info!("send fast to foreend");
let backend = GLOBAL_BACKEND.get().unwrap();
let path = path.to_str().unwrap_or("").to_string();
let params = UpdateFastNotification { fast, path };
info!("backend client: {:?}", backend.client);
backend.client.send_notification::<UpdateFastNotification>(params).await;
}