diff --git a/sway-lsp/src/traverse/parsed_tree.rs b/sway-lsp/src/traverse/parsed_tree.rs
index 9b591ddbc55..3c5adbd17be 100644
--- a/sway-lsp/src/traverse/parsed_tree.rs
+++ b/sway-lsp/src/traverse/parsed_tree.rs
@@ -24,7 +24,7 @@ use sway_core::{
StructExpression, StructScrutineeField, SubfieldExpression, TraitFn, TreeType,
TupleIndexExpression, UseStatement, WhileLoopExpression,
},
- Literal,
+ CallPathTree, Literal,
},
transform::{AttributeKind, AttributesMap},
type_system::{TypeArgument, TypeParameter},
@@ -823,35 +823,29 @@ impl<'a> ParsedTree<'a> {
self.collect_type_arg(type_arg, &token);
}
}
- TypeInfo::Custom {
- call_path,
- type_arguments,
- } => {
- if let Some(type_args) = type_arguments {
- for type_arg in type_args {
- self.collect_type_arg(type_arg, &token);
- }
- }
-
+ _ => {
let symbol_kind = type_info_to_symbol_kind(self.type_engine, &type_info);
token.kind = symbol_kind;
- token.type_def = Some(TypeDefinition::TypeId(type_argument.type_id));
- for ident in &call_path.prefixes {
- self.tokens.insert(to_ident_key(ident), token.clone());
+ if let Some(tree) = &type_argument.call_path_tree {
+ self.collect_call_path_tree(tree, &token);
}
- self.tokens.insert(to_ident_key(&call_path.suffix), token);
- }
- _ => {
- let symbol_kind = type_info_to_symbol_kind(self.type_engine, &type_info);
- token.kind = symbol_kind;
- token.type_def = Some(TypeDefinition::TypeId(type_argument.type_id));
- self.tokens
- .insert(to_ident_key(&Ident::new(type_argument.span.clone())), token);
}
}
}
+ fn collect_call_path_tree(&self, tree: &CallPathTree, token: &Token) {
+ for ident in &tree.call_path.prefixes {
+ self.tokens.insert(to_ident_key(ident), token.clone());
+ }
+ self.tokens
+ .insert(to_ident_key(&tree.call_path.suffix), token.clone());
+
+ for child in &tree.children {
+ self.collect_call_path_tree(child, token);
+ }
+ }
+
fn collect_scrutinee(&self, scrutinee: &Scrutinee) {
match scrutinee {
Scrutinee::CatchAll { .. } => (),
diff --git a/sway-lsp/src/traverse/typed_tree.rs b/sway-lsp/src/traverse/typed_tree.rs
index 15c1fa43a9b..ba7364a686c 100644
--- a/sway-lsp/src/traverse/typed_tree.rs
+++ b/sway-lsp/src/traverse/typed_tree.rs
@@ -710,13 +710,11 @@ impl<'a> TypedTree<'a> {
ty::TyExpressionVariant::AbiCast {
abi_name, address, ..
} => {
- for ident in &abi_name.prefixes {
- if let Some(mut token) =
- self.tokens.try_get_mut(&to_ident_key(ident)).try_unwrap()
- {
- token.typed = Some(TypedAstToken::TypedExpression(expression.clone()));
- }
- }
+ self.collect_call_path_prefixes(
+ &abi_name.prefixes,
+ TypedAstToken::TypedExpression(expression.clone()),
+ namespace,
+ );
if let Some(mut token) = self
.tokens
@@ -724,6 +722,13 @@ impl<'a> TypedTree<'a> {
.try_unwrap()
{
token.typed = Some(TypedAstToken::TypedExpression(expression.clone()));
+ if let Some(abi_def_ident) = namespace
+ .submodule(&abi_name.prefixes)
+ .and_then(|module| module.symbols().get(&abi_name.suffix))
+ .and_then(|decl| decl.get_decl_ident())
+ {
+ token.type_def = Some(TypeDefinition::Ident(abi_def_ident));
+ }
}
self.handle_expression(address, namespace);
@@ -1063,23 +1068,42 @@ impl<'a> TypedTree<'a> {
self.collect_call_path_tree(child_tree, &type_arg, namespace);
}
}
- TypeInfo::Custom { type_arguments, .. } => {
- if let Some(type_args) = type_arguments {
- for (child_tree, type_arg) in tree.children.iter().zip(type_args.iter()) {
- self.collect_call_path_tree(child_tree, type_arg, namespace);
- }
+ TypeInfo::Custom {
+ type_arguments: Some(type_args),
+ ..
+ } => {
+ for (child_tree, type_arg) in tree.children.iter().zip(type_args.iter()) {
+ self.collect_call_path_tree(child_tree, type_arg, namespace);
}
}
- _ => {
- self.collect_type_id(
- type_arg.type_id,
- &TypedAstToken::TypedArgument(type_arg.clone()),
- // use the whole span instead of just the name if we don't know
- // how to walk it
- type_arg.span(),
- namespace,
- );
+ TypeInfo::ContractCaller { .. } => {
+ // single generic argument to ContractCaller<_> has to be a single ABI
+ // definition call path which we can collect without recursion
+ if let Some(child_tree) = tree.children.first() {
+ let abi_call_path = &child_tree.call_path;
+
+ self.collect_call_path_prefixes(
+ &abi_call_path.prefixes,
+ TypedAstToken::TypedArgument(type_arg.clone()),
+ namespace,
+ );
+ if let Some(mut token) = self
+ .tokens
+ .try_get_mut(&to_ident_key(&abi_call_path.suffix))
+ .try_unwrap()
+ {
+ token.typed = Some(TypedAstToken::TypedArgument(type_arg.clone()));
+ if let Some(abi_def_ident) = namespace
+ .submodule(&abi_call_path.prefixes)
+ .and_then(|module| module.symbols().get(&abi_call_path.suffix))
+ .and_then(|decl| decl.get_decl_ident())
+ {
+ token.type_def = Some(TypeDefinition::Ident(abi_def_ident));
+ }
+ }
+ }
}
+ _ => {}
};
}
diff --git a/sway-lsp/tests/fixtures/tokens/variables/src/main.sw b/sway-lsp/tests/fixtures/tokens/variables/src/main.sw
index 26e54f8db4b..bc4ff864d22 100644
--- a/sway-lsp/tests/fixtures/tokens/variables/src/main.sw
+++ b/sway-lsp/tests/fixtures/tokens/variables/src/main.sw
@@ -13,6 +13,8 @@ fn example_function(variable: Result