diff --git a/toolchains/solidity/core/Cargo.lock b/toolchains/solidity/core/Cargo.lock index d377d620..868975a9 100644 --- a/toolchains/solidity/core/Cargo.lock +++ b/toolchains/solidity/core/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -57,9 +57,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3a318f1f38d2418400f8209655bfd825785afd25aa30bb7ba6cc792e4596748" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys 0.52.0", ] @@ -88,7 +88,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -188,7 +188,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -205,20 +205,19 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" dependencies = [ "cfg-if", "crossbeam-utils", @@ -226,9 +225,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" dependencies = [ "cfg-if", ] @@ -324,7 +323,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -412,22 +411,11 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "lazy_static" @@ -437,9 +425,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "linter-server" @@ -476,9 +464,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lsp-server" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52dccdf3302eefab8c8a1273047f0a3c3dca4b527c8458d00c09484c8371928" +checksum = "fb69ba934913ebf0ef3b3dd762f0149bf993decd571d094b646de09c2e456732" dependencies = [ "crossbeam-channel", "log", @@ -546,9 +534,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "os" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "9ffda62bb984a82b17675005290ffa19b76fb74c3774cb8bed86bccb628ca911" [[package]] name = "osmium-libs-foundry-wrapper" @@ -579,7 +573,7 @@ version = "0.1.2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", "syn-solidity", "thiserror", ] @@ -636,7 +630,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -739,9 +733,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", @@ -752,9 +746,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "scopeguard" @@ -779,7 +773,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -801,7 +795,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -822,6 +816,20 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slither-server" +version = "0.3.0" +dependencies = [ + "colored", + "os", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "tokio", + "tower-lsp", +] + [[package]] name = "smallvec" version = "1.11.2" @@ -883,9 +891,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -901,7 +909,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -921,7 +929,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -941,9 +949,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -966,7 +974,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1034,7 +1042,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1062,7 +1070,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1076,9 +1084,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" diff --git a/toolchains/solidity/core/crates/slither-server/Cargo.toml b/toolchains/solidity/core/crates/slither-server/Cargo.toml new file mode 100644 index 00000000..bdf4d969 --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "slither-server" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +exclude.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +os = "0.1.0" +serde = "1.0.193" +serde_derive = "1.0.193" +serde_json = "1.0.108" +tokio = { version="1.34.0", features = ["full"] } +tower-lsp = "0.20.0" +colored = "2.0.4" +thiserror = "1.0.50" diff --git a/toolchains/solidity/core/crates/slither-server/src/error.rs b/toolchains/solidity/core/crates/slither-server/src/error.rs new file mode 100644 index 00000000..c8526990 --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum SlitherError { + #[error("Error while runing slither")] + Unknown, + #[error("Error while runing the slither command: {0}")] + IoCommandError(#[from] std::io::Error), + #[error("Error while parsing slither output: {0}")] + ParsingFailed(#[from] serde_json::Error), +} diff --git a/toolchains/solidity/core/crates/slither-server/src/main.rs b/toolchains/solidity/core/crates/slither-server/src/main.rs new file mode 100644 index 00000000..bf78bd26 --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/src/main.rs @@ -0,0 +1,171 @@ +mod error; +mod slither; +mod types; + +use crate::error::SlitherError; +use crate::slither::*; +use tower_lsp::jsonrpc::Result; +use tower_lsp::lsp_types::*; +use tower_lsp::{Client, LanguageServer, LspService, Server}; + +#[derive(Debug)] +struct Backend { + client: Client, +} + +#[tower_lsp::async_trait] +impl LanguageServer for Backend { + async fn initialize(&self, _: InitializeParams) -> Result { + if !is_slither_installed() { + self.client + .show_message( + MessageType::ERROR, + "Slither is not installed! Please install it and restart the extension", + ) + .await; + self.client + .log_message(MessageType::ERROR, "Slither is not installed!") + .await; + return Err(tower_lsp::jsonrpc::Error::internal_error()); + } + if !is_solc_installed() { + self.client + .show_message( + MessageType::ERROR, + "Solc is not installed! Please install it and restart the extension", + ) + .await; + self.client + .log_message(MessageType::ERROR, "Solc is not installed!") + .await; + return Err(tower_lsp::jsonrpc::Error::internal_error()); + } + Ok(InitializeResult { + server_info: None, + capabilities: ServerCapabilities { + text_document_sync: Some(TextDocumentSyncCapability::Kind( + TextDocumentSyncKind::INCREMENTAL, + )), + workspace: Some(WorkspaceServerCapabilities { + workspace_folders: Some(WorkspaceFoldersServerCapabilities { + supported: Some(true), + change_notifications: Some(OneOf::Left(true)), + }), + file_operations: None, + }), + ..ServerCapabilities::default() + }, + }) + } + + async fn initialized(&self, _: InitializedParams) { + self.client + .log_message(MessageType::INFO, "osmium-slither initialized!") + .await; + } + + async fn shutdown(&self) -> Result<()> { + Ok(()) + } + + async fn did_open(&self, file: DidOpenTextDocumentParams) { + self.client + .log_message( + MessageType::INFO, + format!( + "Opened file '{}' for analyzing.", + file.text_document.uri.path() + ), + ) + .await; + if file.text_document.uri.path().ends_with(".t.sol") { + self.client + .log_message( + MessageType::INFO, + format!( + "File '{}' is a test solidity file, skipping analysis.", + file.text_document.uri.path() + ), + ) + .await; + return; + } + self.check_slither_result(file.text_document.uri).await + } + + async fn did_save(&self, file: DidSaveTextDocumentParams) { + self.client + .log_message( + MessageType::INFO, + format!( + "Saved file '{}' for analyzing.", + file.text_document.uri.path() + ), + ) + .await; + if file.text_document.uri.path().ends_with(".t.sol") { + self.client + .log_message( + MessageType::INFO, + format!( + "File '{}' is a test solidity file, skipping analysis.", + file.text_document.uri.path() + ), + ) + .await; + return; + } + self.check_slither_result(file.text_document.uri).await + } +} + +impl Backend { + async fn check_slither_result(&self, uri: Url) { + let res = exec_slither(uri.path()); + match res { + Ok(res) => { + self.client + .log_message( + MessageType::INFO, + format!( + "File '{}' did generate {} security diagnostics.", + uri.path(), + res.len() + ), + ) + .await; + self.client.publish_diagnostics(uri, res, None).await; + } + Err(SlitherError::ParsingFailed(e)) => { + self.client + .log_message( + MessageType::ERROR, + format!( + "File '{}' did generate an error while parsing the output: {:?}", + uri.path(), + e + ), + ) + .await; + self.client.publish_diagnostics(uri, vec![], None).await; + } + Err(e) => { + self.client + .log_message( + MessageType::ERROR, + format!("File '{}' did generate an error: {:?}", uri.path(), e), + ) + .await; + } + } + } +} + +#[tokio::main] +async fn main() { + let stdin = tokio::io::stdin(); + let stdout = tokio::io::stdout(); + + let (service, socket) = LspService::new(|client| Backend { client }); + Server::new(stdin, stdout, socket).serve(service).await; +} diff --git a/toolchains/solidity/core/crates/slither-server/src/slither.rs b/toolchains/solidity/core/crates/slither-server/src/slither.rs new file mode 100644 index 00000000..f23586eb --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/src/slither.rs @@ -0,0 +1,50 @@ +use crate::error::SlitherError; +use crate::types::SlitherResult; +use std::process::Command; +use tower_lsp::lsp_types::Diagnostic; + +pub fn is_slither_installed() -> bool { + let output = Command::new("slither").arg("--version").output(); + output.is_ok() +} + +pub fn is_solc_installed() -> bool { + let output = Command::new("solc").arg("--version").output(); + output.is_ok() +} + +#[cfg(target_family = "windows")] +fn normalize_slither_path(path: &str) -> String { + let mut path = path.replace("%3A/", "://"); + path.remove(0); + path.to_string() +} + +#[cfg(not(target_family = "windows"))] +fn normalize_slither_path(path: &str) -> String { + path.to_string() +} + +pub fn exec_slither(filepath: &str) -> Result, SlitherError> { + let mut results: Vec = Vec::new(); + let out = Command::new("slither") + .arg(normalize_slither_path(filepath)) + .arg("--exclude") + .arg("naming-convention") + .arg("--json") + .arg("-") + .output()?; + if out.status.code() == Some(1) { + eprintln!("Unknown error occured: {:?}", out); + return Err(SlitherError::Unknown); + } + if out.stdout.is_empty() { + return Ok(results); + } + let json: SlitherResult = + serde_json::from_str(&String::from_utf8_lossy(&out.stdout).replace("\\\"", "\""))?; + for detector in json.results.detectors { + results.append(&mut crate::types::diag_from_json(detector.clone())); + } + Ok(results) +} diff --git a/toolchains/solidity/core/crates/slither-server/src/types.rs b/toolchains/solidity/core/crates/slither-server/src/types.rs new file mode 100644 index 00000000..0486f555 --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/src/types.rs @@ -0,0 +1,125 @@ +use serde::{Deserialize, Serialize}; +use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity as Severity, Position, Range}; + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherResult { + pub results: SlitherResults, + pub success: bool, + pub error: Option, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherResults { + pub detectors: Vec, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherDetector { + pub elements: Vec, + pub description: String, + pub check: String, + pub impact: String, + pub id: String, + pub confidence: String, + pub markdown: String, + pub first_markdown_element: String, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherElement { + pub source_mapping: SlitherSourceMapping, + + #[serde(rename = "type")] + pub type_: String, + pub name: String, + pub type_specific_fields: Option, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherSourceMapping { + pub filename_absolute: String, + pub filename_relative: String, + pub filename_short: String, + pub is_dependency: bool, + pub lines: Vec, + pub starting_column: usize, + pub ending_column: usize, + pub length: usize, + pub start: usize, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherTypeSpecificFields { + pub directive: Option>, + pub signature: Option, + pub additional_fields: Option, + pub parent: Option, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherParent { + pub name: String, + #[serde(rename = "type")] + pub type_: String, + pub type_specific_fields: Option>, + pub source_mapping: Option, + pub signature: Option, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct SlitherAdditionalFields { + pub underlying_type: Option, + pub visibility: Option, + pub variable_name: Option, +} + +pub fn diag_from_json(json: SlitherDetector) -> Vec { + let mut results: Vec = Vec::new(); + + for idx in 0..json.elements.len() { + if json.elements[idx].source_mapping.lines.is_empty() + || json.elements[idx].type_ == "contract" + { + continue; + } + let lines = &json.elements[idx].source_mapping.lines; + let start_col = json.elements[idx].source_mapping.starting_column; + let end_col = json.elements[idx].source_mapping.ending_column; + let range = Range { + start: Position { + line: lines[0] as u32 - 1, + character: start_col as u32 - 1, + }, + end: Position { + line: lines[lines.len() - 1] as u32 - 1, + character: end_col as u32, + }, + }; + + let severity = match json.impact.as_str() { + "High" => Severity::ERROR, + "Medium" => Severity::WARNING, + "Low" => Severity::HINT, + "Informational" => Severity::INFORMATION, + _ => Severity::ERROR, + }; + + results.push(Diagnostic { + range, + severity: Some(severity), + code: None, + code_description: None, + source: Some("osmium-slither".to_string()), + message: json.description.to_string() + "\nCheck: " + &json.check, + related_information: None, + tags: None, + data: None, + }); + } + + results +} + +//////////////////////////////////////////////////////////// +/////////////////// RELATED TYPES: ///////////////////////// +//////////////////////////////////////////////////////////// diff --git a/toolchains/solidity/core/crates/slither-server/test.json b/toolchains/solidity/core/crates/slither-server/test.json new file mode 100644 index 00000000..e6a2a763 --- /dev/null +++ b/toolchains/solidity/core/crates/slither-server/test.json @@ -0,0 +1,860 @@ +{ + "success": true, + "error": null, + "results": { + "detectors": [ + { + "elements": [ + { + "type": "variable", + "name": "test", + "source_mapping": { + "start": 293, + "length": 16, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 10 + ], + "starting_column": 9, + "ending_column": 25 + }, + "type_specific_fields": { + "parent": { + "type": "function", + "name": "test", + "source_mapping": { + "start": 230, + "length": 254, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + "starting_column": 5, + "ending_column": 6 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + }, + "signature": "test()" + } + } + } + }, + { + "type": "function", + "name": "test", + "source_mapping": { + "start": 230, + "length": 254, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + "starting_column": 5, + "ending_column": 6 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + }, + "signature": "test()" + } + } + ], + "description": "Test.test().test (VarNameMixedCase/file.sol#10) shadows:\n\t- Test.test() (VarNameMixedCase/file.sol#9-15) (function)\n", + "markdown": "[Test.test().test](VarNameMixedCase/file.sol#L10) shadows:\n\t- [Test.test()](VarNameMixedCase/file.sol#L9-L15) (function)\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L10", + "id": "cd02f0d58377d623f3c8889edc1f9cef4c816f5f91b6dc77ec5ab0a30f0da89a", + "check": "shadowing-local", + "impact": "Low", + "confidence": "High" + }, + { + "elements": [ + { + "type": "pragma", + "name": "^0.8.0", + "source_mapping": { + "start": 0, + "length": 23, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 1 + ], + "starting_column": 1, + "ending_column": 24 + }, + "type_specific_fields": { + "directive": [ + "solidity", + "^", + "0.8", + ".0" + ] + } + } + ], + "description": "Pragma version^0.8.0 (VarNameMixedCase/file.sol#1) allows old versions\n", + "markdown": "Pragma version[^0.8.0](VarNameMixedCase/file.sol#L1) allows old versions\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L1", + "id": "2dda11de37b3076df14acf93394be6277599b82b9eee970c37fab5b9b1b8005a", + "check": "solc-version", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [], + "description": "solc-0.8.0 is not recommended for deployment\n", + "markdown": "solc-0.8.0 is not recommended for deployment\n", + "first_markdown_element": "", + "id": "c298e4718eba1e635e63e4c3206d561ac1974eaef1a3bba154ff9c56bcf6282a", + "check": "solc-version", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test_contract_for_linter", + "source_mapping": { + "start": 172, + "length": 36, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 7 + ], + "starting_column": 5, + "ending_column": 41 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + }, + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } + } + ], + "description": "Variable Test.test_contract_for_linter (VarNameMixedCase/file.sol#7) is not in mixedCase\n", + "markdown": "Variable [Test.test_contract_for_linter](VarNameMixedCase/file.sol#L7) is not in mixedCase\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L7", + "id": "4e48c72cfd518c91e9520f8e00950ca6857a81e2e829c5d2cf15090f07337b4e", + "check": "naming-convention", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test_contract_for_linter", + "source_mapping": { + "start": 172, + "length": 36, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 7 + ], + "starting_column": 5, + "ending_column": 41 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + }, + { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + ], + "description": "Test.test_contract_for_linter (VarNameMixedCase/file.sol#7) is never used in Test (VarNameMixedCase/file.sol#3-16)\n", + "markdown": "[Test.test_contract_for_linter](VarNameMixedCase/file.sol#L7) is never used in [Test](VarNameMixedCase/file.sol#L3-L16)\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L7", + "id": "249b0e713ea45bf6437843661e45195736cb77b9f51e8567b2efab053a8b5a79", + "check": "unused-state", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "contracts", + "source_mapping": { + "start": 48, + "length": 21, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 4 + ], + "starting_column": 5, + "ending_column": 26 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + }, + { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + ], + "description": "Test.contracts (VarNameMixedCase/file.sol#4) is never used in Test (VarNameMixedCase/file.sol#3-16)\n", + "markdown": "[Test.contracts](VarNameMixedCase/file.sol#L4) is never used in [Test](VarNameMixedCase/file.sol#L3-L16)\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L4", + "id": "4a65411183e0d7542dfef6c8fbf65127f35f02df5c617af7f34b249d00b6170b", + "check": "unused-state", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "testContractForLinter", + "source_mapping": { + "start": 123, + "length": 33, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 6 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + }, + { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + ], + "description": "Test.testContractForLinter (VarNameMixedCase/file.sol#6) is never used in Test (VarNameMixedCase/file.sol#3-16)\n", + "markdown": "[Test.testContractForLinter](VarNameMixedCase/file.sol#L6) is never used in [Test](VarNameMixedCase/file.sol#L3-L16)\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L6", + "id": "a838f6c866f803a79379bef45de3562aea0b2bd25b45a236b1f20a1241e3f2bb", + "check": "unused-state", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "_contract2", + "source_mapping": { + "start": 85, + "length": 22, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 5 + ], + "starting_column": 5, + "ending_column": 27 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + }, + { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + ], + "description": "Test._contract2 (VarNameMixedCase/file.sol#5) is never used in Test (VarNameMixedCase/file.sol#3-16)\n", + "markdown": "[Test._contract2](VarNameMixedCase/file.sol#L5) is never used in [Test](VarNameMixedCase/file.sol#L3-L16)\n", + "first_markdown_element": "VarNameMixedCase/file.sol#L5", + "id": "ecf8c5b3c78ca9c1e8015e0726d5ccb9d6a3e6584d0e7c8a779fba5abea92640", + "check": "unused-state", + "impact": "Informational", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "contracts", + "source_mapping": { + "start": 48, + "length": 21, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 4 + ], + "starting_column": 5, + "ending_column": 26 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Test.contracts (VarNameMixedCase/file.sol#4) should be constant \n", + "markdown": "[Test.contracts](VarNameMixedCase/file.sol#L4) should be constant \n", + "first_markdown_element": "VarNameMixedCase/file.sol#L4", + "id": "6db1de55012a570ba924671b4431a1fb4aa17a1312a12c385b19cab0ac0cdbac", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "_contract2", + "source_mapping": { + "start": 85, + "length": 22, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 5 + ], + "starting_column": 5, + "ending_column": 27 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Test._contract2 (VarNameMixedCase/file.sol#5) should be constant \n", + "markdown": "[Test._contract2](VarNameMixedCase/file.sol#L5) should be constant \n", + "first_markdown_element": "VarNameMixedCase/file.sol#L5", + "id": "81ce76bdea73dfd45eb250dc7e2437ec8b3ed809bbe65651577a7e8a06bd8940", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "test_contract_for_linter", + "source_mapping": { + "start": 172, + "length": 36, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 7 + ], + "starting_column": 5, + "ending_column": 41 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Test.test_contract_for_linter (VarNameMixedCase/file.sol#7) should be constant \n", + "markdown": "[Test.test_contract_for_linter](VarNameMixedCase/file.sol#L7) should be constant \n", + "first_markdown_element": "VarNameMixedCase/file.sol#L7", + "id": "9420b4e072bd069f87d9bd6212424e443a593b4d6c6fc9a43c86f346d98f916f", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + }, + { + "elements": [ + { + "type": "variable", + "name": "testContractForLinter", + "source_mapping": { + "start": 123, + "length": 33, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 6 + ], + "starting_column": 5, + "ending_column": 38 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "Test", + "source_mapping": { + "start": 27, + "length": 460, + "filename_relative": "VarNameMixedCase/file.sol", + "filename_absolute": "C:\\Users\\trigr\\Work\\astrodevs-labs\\osmium\\toolchains\\solidity\\core\\crates\\linter-lib\\testdata\\VarNameMixedCase\\file.sol", + "filename_short": "VarNameMixedCase/file.sol", + "is_dependency": false, + "lines": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "starting_column": 1, + "ending_column": 2 + } + } + } + } + ], + "description": "Test.testContractForLinter (VarNameMixedCase/file.sol#6) should be constant \n", + "markdown": "[Test.testContractForLinter](VarNameMixedCase/file.sol#L6) should be constant \n", + "first_markdown_element": "VarNameMixedCase/file.sol#L6", + "id": "ff4df4c88e398e8a146a65bedf8261150643c59f4f37e678398b043cd7426732", + "check": "constable-states", + "impact": "Optimization", + "confidence": "High" + } + ] + } +} \ No newline at end of file diff --git a/toolchains/solidity/extension/.gitignore b/toolchains/solidity/extension/.gitignore new file mode 100644 index 00000000..c195d8dc --- /dev/null +++ b/toolchains/solidity/extension/.gitignore @@ -0,0 +1,2 @@ +!.vscode/launch.json +!.vscode/tasks.json diff --git a/toolchains/solidity/extension/src/extension.ts b/toolchains/solidity/extension/src/extension.ts index 9d60596e..6994e89d 100644 --- a/toolchains/solidity/extension/src/extension.ts +++ b/toolchains/solidity/extension/src/extension.ts @@ -2,25 +2,26 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ - -import * as path from 'path'; import { workspace, ExtensionContext } from 'vscode'; -[] import { LanguageClient, } from 'vscode-languageclient/node'; import { createLinterClient } from './linter'; import { createFoundryCompilerClient } from './foundry-compiler'; +import { createSlitherClient } from './slither'; +let slitherClient: LanguageClient; let linterClient: LanguageClient; let foundryCompilerClient: LanguageClient; export async function activate(context: ExtensionContext) { linterClient = createLinterClient(context); foundryCompilerClient = createFoundryCompilerClient(context); + slitherClient = createSlitherClient(context); context.subscriptions.push(linterClient); context.subscriptions.push(foundryCompilerClient); + context.subscriptions.push(slitherClient); const folders = workspace.workspaceFolders; diff --git a/toolchains/solidity/extension/src/slither.ts b/toolchains/solidity/extension/src/slither.ts new file mode 100644 index 00000000..ac1128e8 --- /dev/null +++ b/toolchains/solidity/extension/src/slither.ts @@ -0,0 +1,61 @@ +import * as path from 'path'; +import * as os from 'os'; +import { workspace, ExtensionContext, Uri } from "vscode"; +import { + LanguageClient, + LanguageClientOptions, + ServerOptions, + TransportKind +} from 'vscode-languageclient/node'; +import { TextDecoder } from 'util'; + +export function createSlitherClient(context: ExtensionContext): LanguageClient { + // The server is implemented in node + const serverBinary = context.asAbsolutePath( + path.join( + 'dist', + os.platform().startsWith("win") ? 'slither-server.exe' : 'slither-server' + ) + ); + + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + const serverOptions: ServerOptions = { + run: { command: serverBinary, transport: TransportKind.stdio }, + debug: { + command: serverBinary, + transport: TransportKind.stdio, + } + }; + + // Options to control the language client + const clientOptions: LanguageClientOptions = { + // Register the server for plain text documents + documentSelector: [{ scheme: 'file', language: 'solidity' }], + synchronize: { + // Notify the server about file changes to '.clientrc files contained in the workspace + fileEvents: workspace.createFileSystemWatcher('**/.solidhunter.json') + } + }; + + // Create the language client and start the client. + const client = new LanguageClient( + 'osmium-slither', + 'Osmium Slither Language Server', + serverOptions, + clientOptions + ); + + client.onRequest('osmium/getContent', async (params: { uri: string}) => { + const contentUint8 = await workspace.fs.readFile(Uri.parse(params.uri)); + const content = new TextDecoder().decode(contentUint8); + return { + content, + }; + }); + + // Start the client. This will also launch the server + client.start(); + + return client; +} \ No newline at end of file diff --git a/toolchains/solidity/extension/webpack.config.js b/toolchains/solidity/extension/webpack.config.js index ac2e9abb..0bb3bb71 100644 --- a/toolchains/solidity/extension/webpack.config.js +++ b/toolchains/solidity/extension/webpack.config.js @@ -1,7 +1,6 @@ //@ts-check 'use strict'; - const path = require('path'); //@ts-check @@ -22,7 +21,7 @@ const extensionConfig = { libraryTarget: 'commonjs2' }, externals: { - vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ + vscode: 'commonjs vscode', // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ // modules added here also need to be added in the .vscodeignore file }, resolve: { diff --git a/toolchains/solidity/package.json b/toolchains/solidity/package.json index f7edb201..9719dc7d 100644 --- a/toolchains/solidity/package.json +++ b/toolchains/solidity/package.json @@ -12,5 +12,8 @@ "test": "cd core && yarn core:test && cd ../extension && yarn extension:test", "format": "cd core && yarn core:format && cd ../extension && yarn extension:format", "publish": "cd core && yarn core:publish && cd ../extension && yarn extension:publish && cd .." + }, + "dependencies": { + "@types/node": "^20.10.1" } } diff --git a/yarn.lock b/yarn.lock index 0f8218f6..8ec74293 100644 --- a/yarn.lock +++ b/yarn.lock @@ -335,6 +335,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.10.1": + version: 20.10.1 + resolution: "@types/node@npm:20.10.1" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 703c3cc5bdb2818a16f87019fe4072bfd66489bb300338970260c5b84dd2129595995c41b28773c3b7d9d1a64f36fec59a741629ec466f2aeddad7a9d0c027ac + languageName: node + linkType: hard + "@types/semver@npm:^7.3.12": version: 7.5.6 resolution: "@types/semver@npm:7.5.6" @@ -3046,6 +3055,8 @@ __metadata: "osmium-solidity@workspace:toolchains/solidity": version: 0.0.0-use.local resolution: "osmium-solidity@workspace:toolchains/solidity" + dependencies: + "@types/node": "npm:^20.10.1" languageName: unknown linkType: soft