147 lines
4.0 KiB
Rust
147 lines
4.0 KiB
Rust
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::definition::get_language_id_by_uri;
|
||
use crate::server::Backend;
|
||
use crate::sources::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;
|
||
future::ready(do_fast(path))
|
||
}
|
||
}
|
||
|
||
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(path: String) -> Result<FastHdlparam> {
|
||
info!("parse hdl path: {:?}", 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 = parse(
|
||
&text,
|
||
&uri,
|
||
&None,
|
||
&includes
|
||
);
|
||
|
||
if let Some(syntax_tree) = parse_result {
|
||
let hdlparam = make_fast_from_syntaxtree(&syntax_tree, &path_buf);
|
||
return Ok(hdlparam);
|
||
}
|
||
|
||
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 UpdateFastNotification {
|
||
pub fast: FastHdlparam
|
||
}
|
||
|
||
impl Notification for UpdateFastNotification {
|
||
const METHOD: &'static str = "update/fast";
|
||
type Params = Self;
|
||
}
|
||
|
||
pub fn update_fast_to_client(backend: Arc<Option<&Backend>>, fast: FastHdlparam) {
|
||
let backend = backend.unwrap();
|
||
let params = UpdateFastNotification { fast };
|
||
backend.client.send_notification::<UpdateFastNotification>(params);
|
||
} |