Add hover

This commit is contained in:
Ayaz Hafiz 2022-08-20 16:24:11 -05:00
parent 9d365a8a57
commit 0db1cd9c28
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
6 changed files with 193 additions and 19 deletions

View file

@ -1,7 +1,7 @@
//! Traversals over the can ast.
use roc_module::{ident::Lowercase, symbol::Symbol};
use roc_region::all::{Loc, Region};
use roc_region::all::{Loc, Position, Region};
use roc_types::{subs::Variable, types::MemberImpl};
use crate::{
@ -657,6 +657,35 @@ impl Visitor for TypeAtVisitor {
}
}
struct TypeAtPositionVisitor {
position: Position,
region_typ: Option<(Region, Variable)>,
}
impl Visitor for TypeAtPositionVisitor {
fn should_visit(&mut self, region: Region) -> bool {
region.contains_pos(self.position)
}
fn visit_expr(&mut self, expr: &Expr, region: Region, var: Variable) {
if region.contains_pos(self.position) {
self.region_typ = Some((region, var));
walk_expr(self, expr, var);
}
}
fn visit_pattern(&mut self, pat: &Pattern, region: Region, opt_var: Option<Variable>) {
if region.contains_pos(self.position) {
if let Some(var) = opt_var {
self.region_typ = Some((region, var));
}
walk_pattern(self, pat);
}
}
}
/// Attempts to find the type of an expression at `region`, if it exists.
pub fn find_type_at(region: Region, decls: &Declarations) -> Option<Variable> {
let mut visitor = TypeAtVisitor { region, typ: None };
@ -675,6 +704,20 @@ pub enum FoundSymbol {
}
/// Given an ability Foo implements foo : ..., returns (T, foo1) if the symbol at the given region is a
/// Like [find_type_at], but descends into the narrowest node containing [position].
pub fn find_closest_type_at(
position: Position,
decls: &Declarations,
) -> Option<(Region, Variable)> {
let mut visitor = TypeAtPositionVisitor {
position,
region_typ: None,
};
visitor.visit_decls(decls);
visitor.region_typ
}
/// Given an ability Foo has foo : ..., returns (T, foo1) if the symbol at the given region is a
/// symbol foo1 that specializes foo for T. Otherwise if the symbol is foo but the specialization
/// is unknown, (Foo, foo) is returned. Otherwise [None] is returned.
pub fn find_symbol_at(

View file

@ -22,6 +22,10 @@ impl Region {
self.start <= other.start && self.end >= other.end
}
pub fn contains_pos(&self, pos: Position) -> bool {
self.start <= pos && self.end >= pos
}
pub fn is_empty(&self) -> bool {
self.start == self.end
}
@ -356,6 +360,7 @@ where
}
}
#[derive(Debug)]
pub struct LineInfo {
line_offsets: Vec<u32>,
}