Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add inlay hints for function call args #1473

Merged
merged 11 commits into from
Jul 10, 2024
Merged
86 changes: 84 additions & 2 deletions kclvm/sema/src/advanced_resolver/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
SymbolSemanticInfo, UnresolvedSymbol, ValueSymbol,
},
},
ty::{Type, TypeKind, SCHEMA_MEMBER_FUNCTIONS},
ty::{self, Type, TypeKind, SCHEMA_MEMBER_FUNCTIONS},
};

use super::AdvancedResolver;
Expand Down Expand Up @@ -573,7 +573,23 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> {

fn walk_call_expr(&mut self, call_expr: &'ctx ast::CallExpr) -> Self::Result {
self.expr(&call_expr.func)?;
self.do_arguments_symbol_resolve(&call_expr.args, &call_expr.keywords)?;
let ty = self
.ctx
.node_ty_map
.borrow()
.get(&self.ctx.get_node_key(&call_expr.func.id))
.unwrap()
.clone();

if let TypeKind::Function(func_ty) = &ty.kind {
self.do_arguments_symbol_resolve_with_hint(
&call_expr.args,
&call_expr.keywords,
true,
&func_ty,
)?;
}

Ok(None)
}

Expand Down Expand Up @@ -1264,6 +1280,72 @@ impl<'ctx> AdvancedResolver<'ctx> {
Ok(())
}

pub fn do_arguments_symbol_resolve_with_hint(
&mut self,
args: &'ctx [ast::NodeRef<ast::Expr>],
kwargs: &'ctx [ast::NodeRef<ast::Keyword>],
with_hint: bool,
func_ty: &ty::FunctionType,
) -> anyhow::Result<()> {
if func_ty.params.is_empty() {
self.do_arguments_symbol_resolve(args, kwargs)?;
} else {
for (arg, param) in args.iter().zip(func_ty.params.iter()) {
self.expr(arg)?;
let symbol_data = self.gs.get_symbols_mut();

if let Some(arg_ref) = symbol_data
.symbols_info
.node_symbol_map
.get(&self.ctx.get_node_key(&arg.id))
{
match arg_ref.get_kind() {
crate::core::symbol::SymbolKind::Value => {
if let Some(value) = symbol_data.values.get_mut(arg_ref.get_id()) {
if with_hint {
value.hint = Some(SymbolHint::VarHint(param.name.clone()));
}
}
}
crate::core::symbol::SymbolKind::Expression => {
Peefy marked this conversation as resolved.
Show resolved Hide resolved
if let Some(expr) = symbol_data.exprs.get_mut(arg_ref.get_id()) {
if with_hint {
expr.hint = Some(SymbolHint::VarHint(param.name.clone()));
}
}
}
_ => {}
}
}
}

for kw in kwargs.iter() {
if let Some(value) = &kw.node.value {
self.expr(value)?;
}
let (start_pos, end_pos): Range = kw.get_span_pos();
let value = self.gs.get_symbols_mut().alloc_value_symbol(
ValueSymbol::new(kw.node.arg.node.get_name(), start_pos, end_pos, None, false),
self.ctx.get_node_key(&kw.id),
self.ctx.current_pkgpath.clone().unwrap(),
);

if let Some(value) = self.gs.get_symbols_mut().values.get_mut(value.get_id()) {
value.sema_info = SymbolSemanticInfo {
ty: self
.ctx
.node_ty_map
.borrow()
.get(&self.ctx.get_node_key(&kw.id))
.map(|ty| ty.clone()),
doc: None,
};
}
}
}
Ok(())
}

pub(crate) fn walk_config_entries(
&mut self,
entries: &'ctx [ast::NodeRef<ast::ConfigEntry>],
Expand Down
4 changes: 3 additions & 1 deletion kclvm/sema/src/core/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,7 @@ pub struct ExpressionSymbol {
pub(crate) name: String,

pub(crate) sema_info: SymbolSemanticInfo,
pub(crate) hint: Option<SymbolHint>,
}

impl Symbol for ExpressionSymbol {
Expand Down Expand Up @@ -2029,7 +2030,7 @@ impl Symbol for ExpressionSymbol {
}

fn get_hint(&self) -> Option<&Self::SymbolHint> {
None
self.hint.as_ref()
}

fn simple_dump(&self) -> String {
Expand Down Expand Up @@ -2072,6 +2073,7 @@ impl ExpressionSymbol {
end,
sema_info: SymbolSemanticInfo::default(),
owner,
hint: None,
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion kclvm/tools/src/LSP/src/inlay_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,12 @@ fn get_hint_label(symbol: &KCLSymbol, hint: &SymbolHint) -> (InlayHintLabelPart,
},
LspPosition::new(
(start.line - 1).try_into().unwrap(),
start.column.unwrap_or(0).try_into().unwrap(),
start
.column
.unwrap_or(1)
.saturating_sub(1)
.try_into()
.unwrap(),
),
),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tools/src/LSP/src/inlay_hints.rs
assertion_line: 118
expression: "format!(\"{:#?}\", res)"
---
Some(
Expand Down Expand Up @@ -246,5 +247,71 @@ Some(
padding_right: None,
data: None,
},
InlayHint {
position: Position {
line: 23,
character: 4,
},
label: LabelParts(
[
InlayHintLabelPart {
value: ": (any, any, any) -> any",
tooltip: None,
location: None,
command: None,
},
],
),
kind: None,
text_edits: None,
tooltip: None,
padding_left: None,
padding_right: None,
data: None,
},
InlayHint {
position: Position {
line: 27,
character: 1,
},
label: LabelParts(
[
InlayHintLabelPart {
value: ": any",
tooltip: None,
location: None,
command: None,
},
],
),
kind: None,
text_edits: None,
tooltip: None,
padding_left: None,
padding_right: None,
data: None,
},
InlayHint {
position: Position {
line: 27,
character: 12,
},
label: LabelParts(
[
InlayHintLabelPart {
value: "y: ",
tooltip: None,
location: None,
command: None,
},
],
),
kind: None,
text_edits: None,
tooltip: None,
padding_left: None,
padding_right: None,
data: None,
},
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ ee = {
a: "asda"
}
ccc = 1Ki

func = lambda x, y, z{
x * y + z
}

k = func(a, 1, z = 2)
Loading