Skip to content

Commit

Permalink
feat(lsp): add goto definition for structs (#3718)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves 

feat(lsp): add goto definition for structs #3707

## Summary\*

LSP server now understands goto definition command issued by Client (ie.
vscode). In case of Struct constructor, member access or method call it
will jump to it's definition.

## Additional Context

## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
  • Loading branch information
kobyhallx and kevaundray authored Dec 13, 2023
1 parent c85b064 commit a576c5b
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,9 +1290,65 @@ impl NodeInterner {
_ => None,
}
}
HirExpression::Constructor(expr) => {
let struct_type = &expr.r#type.borrow();

eprintln!("\n -> Resolve Constructor {struct_type:?}\n");

Some(struct_type.location)
}
HirExpression::MemberAccess(expr_member_access) => {
self.resolve_struct_member_access(expr_member_access)
}
HirExpression::Call(expr_call) => {
let func = expr_call.func;
self.resolve_location(func)
}

_ => None,
}
}

/// Resolves the [Location] of the definition for a given [crate::hir_def::expr::HirMemberAccess]
/// This is used to resolve the location of a struct member access.
/// For example, in the expression `foo.bar` we want to resolve the location of `bar`
/// to the location of the definition of `bar` in the struct `foo`.
fn resolve_struct_member_access(
&self,
expr_member_access: &crate::hir_def::expr::HirMemberAccess,
) -> Option<Location> {
let expr_lhs = &expr_member_access.lhs;
let expr_rhs = &expr_member_access.rhs;

let found_ident = self.nodes.get(expr_lhs.into())?;

let ident = match found_ident {
Node::Expression(HirExpression::Ident(ident)) => ident,
_ => return None,
};

let definition_info = self.definition(ident.id);

let local_id = match definition_info.kind {
DefinitionKind::Local(Some(local_id)) => local_id,
_ => return None,
};

let constructor_expression = match self.nodes.get(local_id.into()) {
Some(Node::Expression(HirExpression::Constructor(constructor_expression))) => {
constructor_expression
}
_ => return None,
};

let struct_type = constructor_expression.r#type.borrow();
let field_names = struct_type.field_names();

match field_names.iter().find(|field_name| field_name.0 == expr_rhs.0) {
Some(found) => Some(Location::new(found.span(), struct_type.location.file)),
None => None,
}
}
}

impl Methods {
Expand Down

0 comments on commit a576c5b

Please sign in to comment.