use glua_code_analysis::SemanticModel;
use glua_parser::{LuaAst, LuaAstNode, LuaAstToken, LuaSyntaxKind};
use lsp_types::{InlineValue, InlineValueVariableLookup, Position};
use rowan::TokenAtOffset;
pub fn build_inline_values(
semantic_model: &SemanticModel,
position: Position,
) -> Option<Vec<InlineValue>> {
let mut result = Vec::new();
let root = semantic_model.get_root();
let document = semantic_model.get_document();
let offset = document.get_offset(position.line as usize, position.character as usize)?;
let token = match root.syntax().token_at_offset(offset) {
TokenAtOffset::Between(left, _) => left,
TokenAtOffset::Single(token) => token,
TokenAtOffset::None => return None,
};
let block = token.parent_ancestors().find_map(|node| {
if node.kind() == LuaSyntaxKind::Block.into() {
Some(node)
} else {
None
}
})?;
let mut node = block;
if let Some(closure) = node.parent()
&& closure.kind() == LuaSyntaxKind::ClosureExpr.into()
{
node = closure;
}
let ast_node = LuaAst::cast(node)?;
for node in ast_node.descendants::<LuaAst>() {
match node {
LuaAst::LuaLocalName(local_name) => {
let name_token = local_name.get_name_token()?;
let value = name_token.get_name_text();
let range = document.to_lsp_range(name_token.get_range())?;
result.push(InlineValue::VariableLookup(InlineValueVariableLookup {
variable_name: Some(value.to_string()),
range,
case_sensitive_lookup: true,
}));
}
LuaAst::LuaParamName(param_name) => {
let name_token = param_name.get_name_token()?;
let value = name_token.get_name_text();
let range = document.to_lsp_range(name_token.get_range())?;
result.push(InlineValue::VariableLookup(InlineValueVariableLookup {
variable_name: Some(value.to_string()),
range,
case_sensitive_lookup: true,
}));
}
LuaAst::LuaNameExpr(name_expr) => {
let name_token = name_expr.get_name_token()?;
let value = name_token.get_name_text();
let range = document.to_lsp_range(name_token.get_range())?;
result.push(InlineValue::VariableLookup(InlineValueVariableLookup {
variable_name: Some(value.to_string()),
range,
case_sensitive_lookup: true,
}));
}
_ => {}
}
}
Some(result)
}