From f7dd2de17b3e57cea00c61f44db545498632b936 Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 28 Nov 2023 16:12:37 -0500 Subject: [PATCH] feat: implement hover info for tuple, list, and contructor pattern elements --- crates/aiken-lang/src/ast.rs | 43 +++++++++++++++++++++++++--------- crates/aiken-lang/src/expr.rs | 2 +- crates/aiken-lsp/src/server.rs | 2 +- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index 9f2959a0..0940857c 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -449,7 +449,7 @@ impl TypedDefinition { #[derive(Debug, Clone, PartialEq)] pub enum Located<'a> { Expression(&'a TypedExpr), - Pattern(&'a TypedPattern, &'a TypedExpr), + Pattern(&'a TypedPattern, Rc), Definition(&'a TypedDefinition), } @@ -964,7 +964,7 @@ impl Pattern { } impl TypedPattern { - pub fn find_node<'a>(&'a self, byte_index: usize, value: &'a TypedExpr) -> Option> { + pub fn find_node<'a>(&'a self, byte_index: usize, value: &Rc) -> Option> { if !self.location().contains(byte_index) { return None; } @@ -973,20 +973,41 @@ impl TypedPattern { Pattern::Int { .. } | Pattern::Var { .. } | Pattern::Assign { .. } - | Pattern::Discard { .. } => Some(Located::Pattern(self, value)), + | Pattern::Discard { .. } => Some(Located::Pattern(self, value.clone())), Pattern::List { elements, .. } | Pattern::Tuple { elems: elements, .. - } => elements - .iter() - .find_map(|e| e.find_node(byte_index, value)) - .or(Some(Located::Pattern(self, value))), + } => match &**value { + Type::Tuple { elems } => elements + .iter() + .zip(elems.iter()) + .find_map(|(e, t)| e.find_node(byte_index, t)) + .or(Some(Located::Pattern(self, value.clone()))), + Type::App { + module, name, args, .. + } if module.is_empty() && name == "List" => elements + .iter() + // this is the same as above but this uses + // cycle to repeat the single type arg for a list + // there's probably a cleaner way to re-use the code + // from this branch and the above. + .zip(args.iter().cycle()) + .find_map(|(e, t)| e.find_node(byte_index, t)) + .or(Some(Located::Pattern(self, value.clone()))), + _ => None, + }, - Pattern::Constructor { arguments, .. } => arguments - .iter() - .find_map(|e| e.value.find_node(byte_index, value)) - .or(Some(Located::Pattern(self, value))), + Pattern::Constructor { + arguments, tipo, .. + } => match &**tipo { + Type::Fn { args, .. } => arguments + .iter() + .zip(args.iter()) + .find_map(|(e, t)| e.value.find_node(byte_index, t)) + .or(Some(Located::Pattern(self, value.clone()))), + _ => None, + }, } } diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index bb94da7f..dce523c5 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -368,7 +368,7 @@ impl TypedExpr { .or_else(|| right.find_node(byte_index)), TypedExpr::Assignment { value, pattern, .. } => pattern - .find_node(byte_index, value) + .find_node(byte_index, &value.tipo()) .or_else(|| value.find_node(byte_index)), TypedExpr::When { diff --git a/crates/aiken-lsp/src/server.rs b/crates/aiken-lsp/src/server.rs index f48b85b8..93ef9443 100644 --- a/crates/aiken-lsp/src/server.rs +++ b/crates/aiken-lsp/src/server.rs @@ -516,7 +516,7 @@ impl Server { expression.definition_location(), Some(expression.tipo()), ), - Located::Pattern(pattern, value) => (pattern.location(), None, pattern.tipo(value)), + Located::Pattern(pattern, tipo) => (pattern.location(), None, Some(tipo)), Located::Definition(_) => return Ok(None), };