diff --git a/libs/solc-wrapper/src/lib.rs b/libs/solc-wrapper/src/lib.rs index 39651f95..091bbfc5 100644 --- a/libs/solc-wrapper/src/lib.rs +++ b/libs/solc-wrapper/src/lib.rs @@ -41,7 +41,7 @@ pub fn get_ast_for_file(base_path: String) -> Result, SolcWrapp solc.current_dir(base_path.clone()).execute()?; let current_time = SystemTime::now().duration_since(init_time).unwrap(); - println!("Finished compiling in: {:?} seconds", current_time.as_secs()); + eprintln!("Finished compiling in: {:?} seconds", current_time.as_secs()); get_ast_from_solc_output(base_path) } @@ -73,7 +73,7 @@ pub fn get_ast_from_solc_output(base_path: String) -> Result, S } let current_time = SystemTime::now().duration_since(init_time).unwrap(); - println!("Finished parsing ast in: {:?} seconds", current_time.as_secs()); + eprintln!("Finished parsing ast in: {:?} seconds", current_time.as_secs()); Ok(ast_files) } diff --git a/libs/solc-wrapper/src/output.rs b/libs/solc-wrapper/src/output.rs index cfd49e07..958f64e3 100644 --- a/libs/solc-wrapper/src/output.rs +++ b/libs/solc-wrapper/src/output.rs @@ -25,7 +25,7 @@ pub fn get_files_from_solc_output(base_path: &str) -> Result, let current_time = SystemTime::now().duration_since(init_time).unwrap(); - println!("Finished retreiving json ast in: {:?} seconds", current_time.as_secs()); + eprintln!("Finished retreiving json ast in: {:?} seconds", current_time.as_secs()); Ok(files) } diff --git a/toolchains/solidity/core/crates/references-server/src/main.rs b/toolchains/solidity/core/crates/references-server/src/main.rs index e717bbe5..d82c9212 100644 --- a/toolchains/solidity/core/crates/references-server/src/main.rs +++ b/toolchains/solidity/core/crates/references-server/src/main.rs @@ -5,10 +5,7 @@ use crate::utils::*; use std::sync::Arc; use tokio::sync::Mutex; use tower_lsp::jsonrpc::Result; -use tower_lsp::lsp_types; use tower_lsp::lsp_types::*; -use tower_lsp::lsp_types::Position as LspPosition; -use tower_lsp::lsp_types::Range as LspRange; use tower_lsp::lsp_types::Location as LspLocation; use tower_lsp::{Client, LanguageServer, LspService, Server}; use solc_references::*; @@ -59,21 +56,15 @@ impl LanguageServer for Backend { self.client .log_message(MessageType::INFO, "osmium-solidity-references initialized!") .await; - let current_time = std::time::SystemTime::now(); if let Err(e) = self.references_provider.lock().await.update_file_content() { self.client.log_message(MessageType::ERROR, format!("Error updating file content: {}", e)).await; } - let elapsed = current_time.elapsed().unwrap(); - self.client.log_message(MessageType::INFO, format!("Finished updating ast in: {:?} seconds", elapsed)).await; } async fn did_save(&self, _: DidSaveTextDocumentParams) { - let current_time = std::time::SystemTime::now(); if let Err(e) = self.references_provider.lock().await.update_file_content() { self.client.log_message(MessageType::ERROR, format!("Error updating file content: {}", e)).await; } - let elapsed = current_time.elapsed().unwrap(); - self.client.log_message(MessageType::INFO, format!("Finished updating ast in: {:?} seconds", elapsed)).await; } async fn references(&self, params: ReferenceParams) -> Result>> { @@ -82,23 +73,13 @@ impl LanguageServer for Backend { let mut position = params.text_document_position.position; position.line += 1; position.character += 1; + let locations = self.references_provider.lock().await.get_references(&normalize_path(uri.path()), solc_references::Position { line: position.line, column: position.character }); let ret: Vec = locations.iter().map(|location| { let mut new_uri = uri.clone(); new_uri.set_path(&escape_path(&location.uri)); - LspLocation { - uri: new_uri, - range: LspRange { - start: LspPosition { - line: location.start.line - 1, - character: location.start.column - 1, - }, - end: LspPosition { - line: location.end.line - 1, - character: location.end.column - 1, - }, - }, - }}).collect(); + location_to_lsp_location(&new_uri, &location) + }).collect(); Ok(Some(ret)) } @@ -108,22 +89,12 @@ impl LanguageServer for Backend { let mut position = params.text_document_position_params.position; position.line += 1; position.character += 1; + let location = self.references_provider.lock().await.get_definition(&normalize_path(uri.path()), solc_references::Position { line: position.line, column: position.character }); + if let Some(location) = location { uri.set_path(&escape_path(&location.uri)); - return Ok(Some(GotoDefinitionResponse::Scalar(lsp_types::Location { - uri: uri, - range: LspRange { - start: LspPosition { - line: location.start.line - 1, - character: location.start.column - 1, - }, - end: LspPosition { - line: location.end.line - 1, - character: location.end.column - 1, - }, - }, - }))); + return Ok(Some(GotoDefinitionResponse::Scalar(location_to_lsp_location(&uri, &location)))); } self.client.log_message(MessageType::INFO, "No definition found").await; Ok(None) @@ -140,12 +111,21 @@ impl Backend { } #[tokio::main] -async fn main() -> tokio::io::Result<()> { +async fn main() { + /* + + USE THIS CODE TO DEBUG + let listener = tokio::net::TcpListener::bind("127.0.0.1:9001").await?; let (stream, _) = listener.accept().await?; let (read, write) = tokio::io::split(stream); + Server::new(read, write, socket).serve(service).await; + */ let (service, socket) = LspService::new(Backend::new); - Server::new(read, write, socket).serve(service).await; - Ok(()) + let stdin = tokio::io::stdin(); + let stdout = tokio::io::stdout(); + Server::new(stdin, stdout, socket).serve(service).await; + + //Ok(()) } diff --git a/toolchains/solidity/core/crates/references-server/src/utils.rs b/toolchains/solidity/core/crates/references-server/src/utils.rs index 69e00c73..46bd5ab0 100644 --- a/toolchains/solidity/core/crates/references-server/src/utils.rs +++ b/toolchains/solidity/core/crates/references-server/src/utils.rs @@ -1,3 +1,5 @@ +use tower_lsp::lsp_types::{Location as LspLocation, Position as LspPosition, Range as LspRange, Url}; + #[cfg(target_family = "windows")] pub fn normalize_path(path: &str) -> String { let mut path = path.replace("%3A/", "://"); @@ -20,4 +22,20 @@ pub fn escape_path(path: &str) -> String { #[cfg(not(target_family = "windows"))] pub fn escape_path(path: &str) -> String { path.to_string() +} + +pub fn location_to_lsp_location(new_uri: &Url, location: &solc_references::Location) -> LspLocation { + LspLocation { + uri: new_uri.clone(), + range: LspRange { + start: LspPosition { + line: location.start.line - 1, + character: location.start.column - 1, + }, + end: LspPosition { + line: location.end.line - 1, + character: location.end.column - 1, + }, + }, + } } \ No newline at end of file diff --git a/toolchains/solidity/extension/src/extension.ts b/toolchains/solidity/extension/src/extension.ts index a89d1f15..480dbab5 100644 --- a/toolchains/solidity/extension/src/extension.ts +++ b/toolchains/solidity/extension/src/extension.ts @@ -20,7 +20,7 @@ let testManager: TestManager; export async function activate(context: ExtensionContext) { linterClient = await createLinterClient(context); -// foundryCompilerClient = createFoundryCompilerClient(context); + foundryCompilerClient = createFoundryCompilerClient(context); slitherClient = await createSlitherClient(context); referencesClient = await createReferencesClient(context); testsPositionsClient = await createTestsPositionsClient(context); @@ -28,7 +28,7 @@ export async function activate(context: ExtensionContext) { testManager = new TestManager(testsPositionsClient, workspace.workspaceFolders[0].uri.fsPath); } - context.subscriptions.push(linterClient, slitherClient, testsPositionsClient, testManager.testController, referencesClient); + context.subscriptions.push(linterClient, slitherClient, foundryCompilerClient, testsPositionsClient, testManager.testController, referencesClient); registerForgeFmtLinter(context); registerGasEstimation(); diff --git a/toolchains/solidity/extension/src/references.ts b/toolchains/solidity/extension/src/references.ts index c0df022b..f0900ed3 100644 --- a/toolchains/solidity/extension/src/references.ts +++ b/toolchains/solidity/extension/src/references.ts @@ -13,6 +13,7 @@ import { TextDecoder } from 'util'; import * as net from 'net'; export async function createReferencesClient(context: ExtensionContext): Promise { + /* let connectionInfo = { port: 9001, host: "127.0.0.1" @@ -26,6 +27,14 @@ export async function createReferencesClient(context: ExtensionContext): Promise }; return Promise.resolve(result); }; + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + const socketOptions: SocketTransport = { + port: 9001, + kind: TransportKind.socket, + }; + */ + // The server is implemented in node const serverBinary = context.asAbsolutePath( path.join( @@ -34,13 +43,15 @@ export async function createReferencesClient(context: ExtensionContext): Promise ) ); - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - const socketOptions: SocketTransport = { - port: 9001, - kind: TransportKind.socket, + 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