chore: reorganizing lsp commands

This commit is contained in:
Noah Santschi-Cooney 2022-03-19 20:26:30 +00:00
parent e001b4a8b1
commit 86100aa008
No known key found for this signature in database
GPG key ID: 3B22282472C8AE48
9 changed files with 157 additions and 193 deletions

165
client/package-lock.json generated
View file

@ -9,7 +9,7 @@
"@rollup/plugin-json": "^4.1.0",
"adm-zip": "^0.5.9",
"encoding": "^0.1.13",
"node-fetch": "^3.2.3",
"node-fetch": "^2.6.7",
"vscode-languageclient": "^7.0.0"
},
"devDependencies": {
@ -202,14 +202,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
"engines": {
"node": ">= 12"
}
},
"node_modules/deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
@ -242,28 +234,6 @@
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"node_modules/fetch-blob": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.4.tgz",
"integrity": "sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
@ -278,17 +248,6 @@
"node": ">= 6"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -452,39 +411,23 @@
"node": "*"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.3.tgz",
"integrity": "sha512-AXP18u4pidSZ1xYXRDPY/8jdv3RAozIt/WLNR/MBGZAz+xjtlr90RvCnsvHQRiXyWliZF/CpytExp32UU67/SA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": "4.x || >=6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
@ -574,6 +517,11 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"node_modules/vscode-jsonrpc": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
@ -609,12 +557,18 @@
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
},
"node_modules/web-streams-polyfill": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz",
"integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==",
"engines": {
"node": ">= 8"
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
@ -780,11 +734,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
@ -811,15 +760,6 @@
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"fetch-blob": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.4.tgz",
"integrity": "sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==",
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
},
"form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
@ -831,14 +771,6 @@
"mime-types": "^2.1.12"
}
},
"formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"requires": {
"fetch-blob": "^3.1.2"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -968,19 +900,12 @@
"brace-expansion": "^1.1.7"
}
},
"node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
},
"node-fetch": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.3.tgz",
"integrity": "sha512-AXP18u4pidSZ1xYXRDPY/8jdv3RAozIt/WLNR/MBGZAz+xjtlr90RvCnsvHQRiXyWliZF/CpytExp32UU67/SA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
"whatwg-url": "^5.0.0"
}
},
"once": {
@ -1046,6 +971,11 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"vscode-jsonrpc": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
@ -1075,10 +1005,19 @@
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
},
"web-streams-polyfill": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz",
"integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA=="
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",

View file

@ -8,7 +8,7 @@
"@rollup/plugin-json": "^4.1.0",
"adm-zip": "^0.5.9",
"encoding": "^0.1.13",
"node-fetch": "^3.2.3",
"node-fetch": "^2.6.7",
"vscode-languageclient": "^7.0.0"
},
"devDependencies": {

View file

@ -1,6 +1,6 @@
import { mkdirSync, promises as fs } from 'fs'
import * as vscode from 'vscode'
import * as lsp from 'vscode-languageclient'
import * as lsp from 'vscode-languageclient/node'
import * as commands from './commands'
import { log } from './log'
import { LanguageClient } from './lspClient'
@ -54,7 +54,7 @@ export class Extension {
const lspBinary = process.env['MCSHADER_DEBUG'] ?
this.context.asAbsolutePath(path.join('server', 'target', 'debug', 'mcshader-lsp')) +
(process.platform === 'win32' ? '.exe' : '') :
path.join(this.context.globalStoragePath, 'mcshader-lsp')
path.join(this.context.globalStorageUri.fsPath, 'mcshader-lsp')
const filewatcherGlob = this.fileAssociationsToGlob(this.getGLSLFileAssociations())

View file

@ -0,0 +1,52 @@
use std::cell::RefCell;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::Path;
use std::rc::Rc;
use petgraph::dot::Config;
use serde_json::Value;
use petgraph::dot;
use anyhow::{format_err, Result};
use slog_scope::info;
use crate::graph::CachedStableGraph;
use super::Invokeable;
pub struct GraphDotCommand {
pub graph: Rc<RefCell<CachedStableGraph>>,
}
impl Invokeable for GraphDotCommand {
fn run_command(&self, root: &Path, _: &[Value]) -> Result<Value> {
let filepath = root.join("graph.dot");
info!("generating dot file"; "path" => filepath.as_os_str().to_str());
let mut file = OpenOptions::new().truncate(true).write(true).create(true).open(filepath).unwrap();
let mut write_data_closure = || -> Result<(), std::io::Error> {
let graph = self.graph.as_ref();
file.seek(std::io::SeekFrom::Start(0))?;
file.write_all("digraph {\n\tgraph [splines=ortho]\n\tnode [shape=box]\n".as_bytes())?;
file.write_all(
dot::Dot::with_config(&graph.borrow().graph, &[Config::GraphContentOnly])
.to_string()
.as_bytes(),
)?;
file.write_all("\n}".as_bytes())?;
file.flush()?;
file.seek(std::io::SeekFrom::Start(0))?;
Ok(())
};
match write_data_closure() {
Err(err) => Err(format_err!("error generating graphviz data: {}", err)),
_ => Ok(Value::Null),
}
}
}

View file

@ -1,78 +1,22 @@
use std::cell::RefCell;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::rc::Rc;
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use petgraph::dot::Config;
use serde_json::Value;
use petgraph::{dot, graph::NodeIndex};
use petgraph::graph::NodeIndex;
use anyhow::{format_err, Result};
use slog_scope::info;
use std::fs;
use crate::dfs;
use crate::{graph::CachedStableGraph, merge_views, url_norm::FromJson};
pub struct CustomCommandProvider {
commands: HashMap<String, Box<dyn Invokeable>>,
}
impl CustomCommandProvider {
pub fn new(commands: Vec<(&str, Box<dyn Invokeable>)>) -> CustomCommandProvider {
CustomCommandProvider {
commands: commands.into_iter().map(|tup| (tup.0.into(), tup.1)).collect(),
}
}
pub fn execute(&self, command: &str, args: &[Value], root_path: &Path) -> Result<Value> {
if self.commands.contains_key(command) {
return self.commands.get(command).unwrap().run_command(root_path, args);
}
Err(format_err!("command doesn't exist"))
}
}
pub trait Invokeable {
fn run_command(&self, root: &Path, arguments: &[Value]) -> Result<Value>;
}
pub struct GraphDotCommand {
pub graph: Rc<RefCell<CachedStableGraph>>,
}
impl Invokeable for GraphDotCommand {
fn run_command(&self, root: &Path, _: &[Value]) -> Result<Value> {
let filepath = root.join("graph.dot");
info!("generating dot file"; "path" => filepath.as_os_str().to_str());
let mut file = OpenOptions::new().truncate(true).write(true).create(true).open(filepath).unwrap();
let mut write_data_closure = || -> Result<(), std::io::Error> {
let graph = self.graph.as_ref();
file.seek(std::io::SeekFrom::Start(0))?;
file.write_all("digraph {\n\tgraph [splines=ortho]\n\tnode [shape=box]\n".as_bytes())?;
file.write_all(dot::Dot::with_config(&graph.borrow().graph, &[Config::GraphContentOnly]).to_string().as_bytes())?;
file.write_all("\n}".as_bytes())?;
file.flush()?;
file.seek(std::io::SeekFrom::Start(0))?;
Ok(())
};
match write_data_closure() {
Err(err) => Err(format_err!("error generating graphviz data: {}", err)),
_ => Ok(Value::Null),
}
}
}
use super::Invokeable;
pub struct VirtualMergedDocument {
pub graph: Rc<RefCell<CachedStableGraph>>,

View file

@ -0,0 +1,31 @@
use std::{collections::HashMap, path::Path};
use serde_json::Value;
use anyhow::{format_err, Result};
pub mod graph_dot;
pub mod merged_includes;
pub struct CustomCommandProvider {
commands: HashMap<String, Box<dyn Invokeable>>,
}
impl CustomCommandProvider {
pub fn new(commands: Vec<(&str, Box<dyn Invokeable>)>) -> CustomCommandProvider {
CustomCommandProvider {
commands: commands.into_iter().map(|tup| (tup.0.into(), tup.1)).collect(),
}
}
pub fn execute(&self, command: &str, args: &[Value], root_path: &Path) -> Result<Value> {
if self.commands.contains_key(command) {
return self.commands.get(command).unwrap().run_command(root_path, args);
}
Err(format_err!("command doesn't exist"))
}
}
pub trait Invokeable {
fn run_command(&self, root: &Path, arguments: &[Value]) -> Result<Value>;
}

View file

@ -5,7 +5,7 @@ use rust_lsp::lsp_types::{notification::*, *};
use petgraph::stable_graph::NodeIndex;
use serde::Deserialize;
use serde_json::{Value, from_value};
use serde_json::{from_value, Value};
use url_norm::FromUrl;
@ -38,14 +38,14 @@ use regex::Regex;
use lazy_static::lazy_static;
mod commands;
mod configuration;
mod consts;
mod dfs;
mod configuration;
mod graph;
mod logging;
mod lsp_ext;
mod merge_views;
mod opengl;
mod logging;
mod url_norm;
#[cfg(test)]
@ -61,7 +61,6 @@ lazy_static! {
fn main() {
let guard = logging::set_logger_with_level(Level::Info);
let stdin = stdin();
let endpoint_output = LSPEndpoint::create_lsp_output_with_output_stream(stdout);
let cache_graph = graph::CachedStableGraph::new();
@ -72,25 +71,25 @@ fn main() {
root: "".into(),
command_provider: None,
opengl_context: Rc::new(opengl::OpenGlContext::new()),
_log_guard: Some(guard),
log_guard: Some(guard),
};
langserver.command_provider = Some(commands::CustomCommandProvider::new(vec![
(
"graphDot",
Box::new(commands::GraphDotCommand {
graph: Rc::clone(&langserver.graph),
Box::new(commands::graph_dot::GraphDotCommand {
graph: langserver.graph.clone(),
}),
),
(
"virtualMerge",
Box::new(commands::VirtualMergedDocument {
graph: Rc::clone(&langserver.graph),
Box::new(commands::merged_includes::VirtualMergedDocument {
graph: langserver.graph.clone(),
}),
),
]));
LSPEndpoint::run_server_from_input(&mut stdin.lock(), endpoint_output, langserver);
LSPEndpoint::run_server_from_input(&mut stdin().lock(), endpoint_output, langserver);
}
struct MinecraftShaderLanguageServer {
@ -99,7 +98,7 @@ struct MinecraftShaderLanguageServer {
root: PathBuf,
command_provider: Option<commands::CustomCommandProvider>,
opengl_context: Rc<dyn opengl::ShaderValidator>,
_log_guard: Option<slog_scope::GlobalLoggerGuard>,
log_guard: Option<slog_scope::GlobalLoggerGuard>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
@ -607,17 +606,17 @@ impl LanguageServerHandling for MinecraftShaderLanguageServer {
logging::slog_with_trace_id(|| {
#[derive(Deserialize)]
struct Configuration {
#[serde(alias ="logLevel")]
log_level: String
#[serde(alias = "logLevel")]
log_level: String,
}
let config: Configuration = from_value(params.settings.as_object().unwrap().get("mcglsl").unwrap().to_owned()).unwrap();
info!("got updated configuration"; "config" => params.settings.as_object().unwrap().get("mcglsl").unwrap().to_string());
configuration::handle_log_level_change(config.log_level, |level| {
self._log_guard = None; // set to None so Drop is invoked
self._log_guard = Some(logging::set_logger_with_level(level));
self.log_guard = None; // set to None so Drop is invoked
self.log_guard = Some(logging::set_logger_with_level(level));
})
});
}
@ -629,6 +628,7 @@ impl LanguageServerHandling for MinecraftShaderLanguageServer {
if !path.starts_with(&self.root) {
return;
}
if self.graph.borrow_mut().find_node(&path) == None {
self.add_file_and_includes_to_graph(&path);
}

View file

@ -103,6 +103,4 @@ impl ShaderValidator for OpenGlContext {
result
}
}
}

View file

@ -49,7 +49,7 @@ fn new_temp_server(opengl_context: Option<Box<dyn opengl::ShaderValidator>>) ->
root: "".into(),
command_provider: None,
opengl_context: context.into(),
_log_guard: Some(guard),
log_guard: Some(guard),
}
}