mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Remove wasm target from langserver
This commit is contained in:
parent
b1fd93f5c5
commit
174e7c0c50
6 changed files with 69 additions and 140 deletions
|
|
@ -8,7 +8,7 @@ use dm::ast::PathOp;
|
|||
use dm::annotation::Annotation;
|
||||
use dm::objtree::{TypeRef, TypeVar, TypeProc, ProcValue};
|
||||
|
||||
use {Engine, Span, io, is_constructor_name, ignore_root};
|
||||
use {Engine, Span, is_constructor_name, ignore_root};
|
||||
use symbol_search::contains;
|
||||
|
||||
pub fn item_var(ty: TypeRef, name: &str, var: &TypeVar) -> CompletionItem {
|
||||
|
|
@ -126,7 +126,7 @@ pub fn combine_tree_path<'a, I>(iter: &I, mut absolute: bool, mut parts: &'a [St
|
|||
prefix_parts.iter().chain(parts).map(|x| &**x)
|
||||
}
|
||||
|
||||
impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
||||
impl<'a> Engine<'a> {
|
||||
pub fn follow_type_path<'b, I>(&'b self, iter: &I, mut parts: &'b [(PathOp, String)]) -> Option<TypePathResult<'b>>
|
||||
where
|
||||
I: Iterator<Item = (Span, &'a Annotation)> + Clone,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,59 @@
|
|||
//! Pluggable backends for input/output handling.
|
||||
//! I/O backend for standard targets.
|
||||
//!
|
||||
//! JSON-RPC over stdin/stdout with Content-Length headers.
|
||||
|
||||
pub trait RequestRead {
|
||||
fn read(&self) -> Option<String>;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
pub fn run_forever<F: FnMut(&str)>(mut f: F) -> ! {
|
||||
loop {
|
||||
let message = read().expect("request bad read");
|
||||
f(&message);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ResponseWrite {
|
||||
fn write(&self, output: String);
|
||||
fn read() -> Option<String> {
|
||||
macro_rules! check {
|
||||
($exp:expr) => {
|
||||
match $exp {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
eprintln!("{:?}", e);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// read the content-length
|
||||
let mut buffer = String::new();
|
||||
check!(io::stdin().read_line(&mut buffer));
|
||||
if buffer.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let size = {
|
||||
let parts: Vec<&str> = buffer.split(' ').collect();
|
||||
if parts.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
if !parts[0].eq_ignore_ascii_case("content-length:") {
|
||||
return None;
|
||||
}
|
||||
check!(usize::from_str_radix(parts[1].trim(), 10))
|
||||
};
|
||||
|
||||
// skip blank line
|
||||
buffer.clear();
|
||||
check!(io::stdin().read_line(&mut buffer));
|
||||
|
||||
// read content
|
||||
let mut content = vec![0; size];
|
||||
check!(io::stdin().read_exact(&mut content));
|
||||
Some(check!(String::from_utf8(content)))
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch="wasm32", path="wasm.rs")]
|
||||
#[cfg_attr(not(target_arch="wasm32"), path="stdio.rs")]
|
||||
mod system;
|
||||
|
||||
pub use self::system::*;
|
||||
pub fn write(output: String) {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout_lock = stdout.lock();
|
||||
write!(stdout_lock, "Content-Length: {}\r\n\r\n{}", output.len(), output).unwrap();
|
||||
stdout_lock.flush().unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
//! I/O backend for standard targets.
|
||||
//!
|
||||
//! JSON-RPC over stdin/stdout with Content-Length headers.
|
||||
|
||||
use Engine;
|
||||
use io::{RequestRead, ResponseWrite};
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
pub fn io_main() {
|
||||
let stdio = StdIo;
|
||||
let context = Default::default();
|
||||
let mut engine = Engine::new(&stdio, &context);
|
||||
loop {
|
||||
let message = stdio.read().expect("request bad read");
|
||||
engine.handle_input(&message);
|
||||
}
|
||||
}
|
||||
|
||||
struct StdIo;
|
||||
|
||||
impl RequestRead for StdIo {
|
||||
fn read(&self) -> Option<String> {
|
||||
macro_rules! check {
|
||||
($exp:expr) => {
|
||||
match $exp {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
eprintln!("{:?}", e);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// read the content-length
|
||||
let mut buffer = String::new();
|
||||
check!(io::stdin().read_line(&mut buffer));
|
||||
if buffer.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let size = {
|
||||
let parts: Vec<&str> = buffer.split(' ').collect();
|
||||
if parts.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
if !parts[0].eq_ignore_ascii_case("content-length:") {
|
||||
return None;
|
||||
}
|
||||
check!(usize::from_str_radix(parts[1].trim(), 10))
|
||||
};
|
||||
|
||||
// skip blank line
|
||||
buffer.clear();
|
||||
check!(io::stdin().read_line(&mut buffer));
|
||||
|
||||
// read content
|
||||
let mut content = vec![0; size];
|
||||
check!(io::stdin().read_exact(&mut content));
|
||||
Some(check!(String::from_utf8(content)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseWrite for StdIo {
|
||||
fn write(&self, output: String) {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout_lock = stdout.lock();
|
||||
write!(stdout_lock, "Content-Length: {}\r\n\r\n{}", output.len(), output).unwrap();
|
||||
stdout_lock.flush().unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//! I/O backend for WebAssembly target.
|
||||
//!
|
||||
//! `main()` creates an engine that will respond to calls to `handle_input()`,
|
||||
//! which will then call `handle_output()` with output messages.
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use Engine;
|
||||
use super::ResponseWrite;
|
||||
|
||||
pub fn io_main() {
|
||||
let wasmio = Box::leak(Box::new(WasmIo));
|
||||
let context = Box::leak(Box::new(Default::default()));
|
||||
let engine = Box::new(Engine::new(wasmio, context));
|
||||
unsafe {
|
||||
ENGINE_PTR = Box::into_raw(engine);
|
||||
return_into_js();
|
||||
}
|
||||
}
|
||||
|
||||
static mut ENGINE_PTR: *mut Engine<WasmIo> = 0 as *mut Engine<WasmIo>;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn handle_input(ptr: *const u8, len: usize) {
|
||||
assert!(!ENGINE_PTR.is_null());
|
||||
let engine = &mut *ENGINE_PTR;
|
||||
let slice = std::slice::from_raw_parts(ptr, len);
|
||||
let text = std::str::from_utf8(slice).expect("input is not utf-8");
|
||||
engine.handle_input(text);
|
||||
}
|
||||
|
||||
struct WasmIo;
|
||||
|
||||
impl ResponseWrite for WasmIo {
|
||||
fn write(&self, output: String) {
|
||||
unsafe {
|
||||
handle_output(output.as_ptr(), output.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
fn handle_output(ptr: *const u8, len: usize);
|
||||
fn return_into_js() -> !;
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ pub mod all_notifications {
|
|||
|
||||
macro_rules! handle_method_call {
|
||||
($(on $what:ident(&mut $self:ident, $p:pat) $b:block)*) => {
|
||||
impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
||||
impl<'a> Engine<'a> {
|
||||
fn handle_method_call(&mut self, call: jsonrpc::MethodCall) -> Result<serde_json::Value, jsonrpc::Error> {
|
||||
use langserver::request::*;
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ macro_rules! handle_method_call {
|
|||
|
||||
macro_rules! handle_notification {
|
||||
($(on $what:ident(&mut $self:ident, $p:pat) $b:block)*) => {
|
||||
impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
||||
impl<'a> Engine<'a> {
|
||||
fn handle_notification(&mut self, notification: jsonrpc::Notification) -> Result<(), jsonrpc::Error> {
|
||||
use macros::all_notifications::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ fn main() {
|
|||
Err(e) => eprintln!("dir check failure: {}", e),
|
||||
}
|
||||
|
||||
io::io_main();
|
||||
let context = dm::Context::default();
|
||||
let mut engine = Engine::new(&context);
|
||||
io::run_forever(|message| engine.handle_input(message));
|
||||
}
|
||||
|
||||
const VERSION: Option<jsonrpc::Version> = Some(jsonrpc::Version::V2);
|
||||
|
|
@ -116,8 +118,7 @@ impl ClientCaps {
|
|||
}
|
||||
}
|
||||
|
||||
struct Engine<'a, W: 'a> {
|
||||
write: &'a W,
|
||||
struct Engine<'a> {
|
||||
docs: document::DocumentStore,
|
||||
|
||||
status: InitStatus,
|
||||
|
|
@ -135,10 +136,9 @@ struct Engine<'a, W: 'a> {
|
|||
client_caps: ClientCaps,
|
||||
}
|
||||
|
||||
impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
||||
fn new(write: &'a W, context: &'a dm::Context) -> Self {
|
||||
impl<'a> Engine<'a> {
|
||||
fn new(context: &'a dm::Context) -> Self {
|
||||
Engine {
|
||||
write,
|
||||
docs: Default::default(),
|
||||
|
||||
status: InitStatus::Starting,
|
||||
|
|
@ -165,7 +165,7 @@ impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
|||
T: langserver::notification::Notification,
|
||||
T::Params: serde::Serialize,
|
||||
{
|
||||
issue_notification::<_, T>(self.write, params)
|
||||
issue_notification::<T>(params)
|
||||
}
|
||||
|
||||
fn show_message<S>(&mut self, typ: MessageType, message: S) where
|
||||
|
|
@ -512,8 +512,7 @@ impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
|||
}
|
||||
}
|
||||
|
||||
issue_notification::<_, langserver::notification::PublishDiagnostics>(
|
||||
self.write,
|
||||
issue_notification::<langserver::notification::PublishDiagnostics>(
|
||||
langserver::PublishDiagnosticsParams {
|
||||
uri: url.to_owned(),
|
||||
diagnostics,
|
||||
|
|
@ -677,7 +676,7 @@ impl<'a, W: io::ResponseWrite> Engine<'a, W> {
|
|||
_ => Response::Batch(outputs),
|
||||
};
|
||||
|
||||
self.write.write(serde_json::to_string(&response).expect("response bad to_string"));
|
||||
io::write(serde_json::to_string(&response).expect("response bad to_string"));
|
||||
}
|
||||
|
||||
fn handle_call(&mut self, call: Call) -> Option<Output> {
|
||||
|
|
@ -1707,7 +1706,7 @@ fn span_to_range(range: ::std::ops::Range<dm::Location>) -> langserver::Range {
|
|||
langserver::Range::new(location_to_position(range.start), location_to_position(range.end))
|
||||
}
|
||||
|
||||
fn issue_notification<W: io::ResponseWrite, T>(write: &W, params: T::Params)
|
||||
fn issue_notification<T>(params: T::Params)
|
||||
where
|
||||
T: langserver::notification::Notification,
|
||||
T::Params: serde::Serialize,
|
||||
|
|
@ -1718,7 +1717,7 @@ where
|
|||
method: T::METHOD.to_owned(),
|
||||
params: value_to_params(params),
|
||||
}));
|
||||
write.write(serde_json::to_string(&request).expect("notification bad to_string"))
|
||||
io::write(serde_json::to_string(&request).expect("notification bad to_string"))
|
||||
}
|
||||
|
||||
fn component_to_source(component: dm::Component) -> Option<String> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue