Skip to content

Commit

Permalink
Implement a runnables custom method and collect typed tokens (FuelLab…
Browse files Browse the repository at this point in the history
…s#2441)

This PR enables the language server to collect and use typed tokens. As a result, go to definition works for tokens that have an associated type definition (roughly 50% of tokens).

This also allows us to get the main_function for script and predicate files, allowing us to send the code position on the main fn back to the client. Code lens is implemented on the client side for now which allows us to have a play button show up above the main fn to execute forc run.

Currently, we are only able to use the typed tokens, and send information about the main fn location if the program is able to successfully compile. This should be fixed once FuelLabs#1674 is addressed.
  • Loading branch information
JoshuaBatty authored Aug 2, 2022
1 parent 541adf2 commit c39bd36
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sway-lsp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ forc = { version = "0.19.1", path = "../forc" }
forc-pkg = { version = "0.19.1", path = "../forc-pkg" }
forc-util = { version = "0.19.1", path = "../forc-util" }
ropey = "1.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.60"
sway-core = { version = "0.19.1", path = "../sway-core" }
sway-fmt = { version = "0.19.1", path = "../sway-fmt" }
Expand Down
1 change: 1 addition & 0 deletions sway-lsp/src/capabilities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pub mod formatting;
pub mod highlight;
pub mod hover;
pub mod rename;
pub mod runnable;
pub mod semantic_tokens;
8 changes: 8 additions & 0 deletions sway-lsp/src/capabilities/runnable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[derive(Debug, Eq, PartialEq, Hash)]
pub enum RunnableType {
/// This is the main_fn entry point for the predicate or script.
MainFn,
/// Place holder for when we have in language testing supported.
/// The field holds the index of the test to run.
_TestFn(u8),
}
25 changes: 18 additions & 7 deletions sway-lsp/src/core/session.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
capabilities::{self, formatting::get_format_text_edits},
capabilities::{self, formatting::get_format_text_edits, runnable::RunnableType},
core::{
document::{DocumentError, TextDocument},
token::{Token, TokenMap, TypeDefinition},
Expand All @@ -16,7 +16,7 @@ use std::{
path::PathBuf,
sync::{Arc, LockResult, RwLock},
};
use sway_core::{CompileAstResult, CompileResult, ParseProgram, TypeInfo};
use sway_core::{CompileAstResult, CompileResult, ParseProgram, TypeInfo, TypedProgramKind};
use sway_types::{Ident, Spanned};
use tower_lsp::lsp_types::{
CompletionItem, Diagnostic, GotoDefinitionParams, GotoDefinitionResponse, Location, Position,
Expand All @@ -30,6 +30,7 @@ pub struct Session {
pub documents: Documents,
pub config: RwLock<SwayConfig>,
pub token_map: TokenMap,
pub runnables: DashMap<RunnableType, Range>,
}

impl Session {
Expand All @@ -38,6 +39,7 @@ impl Session {
documents: DashMap::new(),
config: RwLock::new(SwayConfig::default()),
token_map: DashMap::new(),
runnables: DashMap::new(),
}
}

Expand Down Expand Up @@ -149,6 +151,7 @@ impl Session {

pub fn parse_project(&self, uri: &Url) -> Result<Vec<Diagnostic>, DocumentError> {
self.token_map.clear();
self.runnables.clear();

let manifest_dir = PathBuf::from(uri.path());
let silent_mode = true;
Expand All @@ -161,11 +164,11 @@ impl Session {
pkg::BuildPlan::from_lock_and_manifest(&manifest, locked, offline, SWAY_GIT_TAG)
{
//we can then use them directly to convert them to a Vec<Diagnostic>
if let Ok((parsed_res, _ast_res)) = pkg::check(&plan, silent_mode) {
if let Ok((parsed_res, ast_res)) = pkg::check(&plan, silent_mode) {
// First, populate our token_map with un-typed ast nodes
let res = self.parse_ast_to_tokens(parsed_res);
let _ = self.parse_ast_to_tokens(parsed_res);
// Next, populate our token_map with typed ast nodes
//let res = self.parse_ast_to_typed_tokens(ast_res);
let res = self.parse_ast_to_typed_tokens(ast_res);
//self.test_typed_parse(ast_res);
return res;
}
Expand Down Expand Up @@ -205,7 +208,7 @@ impl Session {
}
}

fn _parse_ast_to_typed_tokens(
fn parse_ast_to_typed_tokens(
&self,
ast_res: CompileAstResult,
) -> Result<Vec<Diagnostic>, DocumentError> {
Expand All @@ -218,6 +221,15 @@ impl Session {
typed_program,
warnings,
} => {
if let TypedProgramKind::Script { main_function, .. }
| TypedProgramKind::Predicate { main_function, .. } = typed_program.kind
{
let main_fn_location =
utils::common::get_range_from_span(&main_function.name.span());
self.runnables
.insert(RunnableType::MainFn, main_fn_location);
}

for node in &typed_program.root.all_nodes {
traverse_typed_tree::traverse_node(node, &self.token_map);
}
Expand All @@ -234,7 +246,6 @@ impl Session {
}

pub fn _test_typed_parse(&mut self, _ast_res: CompileAstResult, uri: &Url) {
// for ((ident, _span), token) in &self.token_map {
for item in self.token_map.iter() {
let ((ident, _span), token) = item.pair();
utils::debug::debug_print_ident_and_token(ident, token);
Expand Down
4 changes: 3 additions & 1 deletion sway-lsp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub async fn start(config: DebugFlags) {
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();

let (service, socket) = LspService::new(|client| Backend::new(client, config));
let (service, socket) = LspService::build(|client| Backend::new(client, config))
.custom_method("sway/runnables", Backend::runnables)
.finish();
Server::new(stdin, stdout, socket).serve(service).await;
}
17 changes: 17 additions & 0 deletions sway-lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::core::{
};
use crate::utils::debug::{self, DebugFlags};
use forc_util::find_manifest_dir;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use sway_utils::helpers::get_sway_files;
use tower_lsp::lsp_types::*;
Expand Down Expand Up @@ -250,6 +251,22 @@ impl LanguageServer for Backend {
}
}

#[derive(Debug, Deserialize, Serialize)]
pub struct RunnableParams {}

// Custom LSP-Server Methods
impl Backend {
pub async fn runnables(&self, _params: RunnableParams) -> jsonrpc::Result<Option<Vec<Range>>> {
let range = self
.session
.runnables
.get(&capabilities::runnable::RunnableType::MainFn)
.map(|item| vec![*item.value()]);

Ok(range)
}
}

#[cfg(test)]
mod tests {
use serde_json::json;
Expand Down

0 comments on commit c39bd36

Please sign in to comment.