|
1 | | -use emmylua_code_analysis::{InferGuard, LuaType, infer_table_field_value_should_be}; |
2 | | -use emmylua_parser::{BinaryOperator, LuaAst, LuaAstNode, LuaBlock, LuaLiteralExpr}; |
| 1 | +use emmylua_code_analysis::{ |
| 2 | + InferGuard, LuaDeclId, LuaType, infer_table_field_value_should_be, infer_table_should_be, |
| 3 | +}; |
| 4 | +use emmylua_parser::{ |
| 5 | + BinaryOperator, LuaAst, LuaAstNode, LuaAstToken, LuaBlock, LuaLiteralExpr, LuaTokenKind, |
| 6 | +}; |
3 | 7 |
|
4 | 8 | use crate::handlers::completion::{ |
5 | 9 | completion_builder::CompletionBuilder, providers::function_provider::dispatch_type, |
@@ -60,11 +64,58 @@ fn get_token_should_type(builder: &mut CompletionBuilder) -> Option<Vec<LuaType> |
60 | 64 | } |
61 | 65 | } |
62 | 66 | } |
63 | | - LuaAst::LuaLocalStat(_) => { |
64 | | - // let locals = local_stat.get_local_name_list().collect::<Vec<_>>(); |
65 | | - // let values = local_stat.get_value_exprs().collect::<Vec<_>>(); |
| 67 | + LuaAst::LuaLocalStat(local_stat) => { |
| 68 | + let locals = local_stat.get_local_name_list().collect::<Vec<_>>(); |
| 69 | + if locals.len() != 1 { |
| 70 | + return None; |
| 71 | + } |
| 72 | + |
| 73 | + let position = builder.trigger_token.text_range().start(); |
| 74 | + let eq = local_stat.token_by_kind(LuaTokenKind::TkAssign)?; |
| 75 | + if position < eq.get_position() { |
| 76 | + return None; |
| 77 | + } |
| 78 | + let local = locals.first()?; |
| 79 | + let decl_id = |
| 80 | + LuaDeclId::new(builder.semantic_model.get_file_id(), local.get_position()); |
| 81 | + let decl_type = builder |
| 82 | + .semantic_model |
| 83 | + .get_db() |
| 84 | + .get_type_index() |
| 85 | + .get_type_cache(&decl_id.into())?; |
| 86 | + return Some(vec![decl_type.as_type().clone()]); |
| 87 | + } |
| 88 | + LuaAst::LuaAssignStat(assign_stat) => { |
| 89 | + let (vars, _) = assign_stat.get_var_and_expr_list(); |
| 90 | + |
| 91 | + if vars.len() != 1 { |
| 92 | + return None; |
| 93 | + } |
| 94 | + |
| 95 | + let position = builder.trigger_token.text_range().start(); |
| 96 | + let eq = assign_stat.token_by_kind(LuaTokenKind::TkAssign)?; |
| 97 | + if position < eq.get_position() { |
| 98 | + return None; |
| 99 | + } |
| 100 | + |
| 101 | + let var = vars.first()?; |
| 102 | + let var_type = builder.semantic_model.infer_expr(var.to_expr()); |
| 103 | + if let Ok(typ) = var_type { |
| 104 | + return Some(vec![typ]); |
| 105 | + } |
| 106 | + } |
| 107 | + LuaAst::LuaTableExpr(table_expr) => { |
| 108 | + let table_type = infer_table_should_be( |
| 109 | + builder.semantic_model.get_db(), |
| 110 | + &mut builder.semantic_model.get_cache().borrow_mut(), |
| 111 | + table_expr, |
| 112 | + ); |
| 113 | + if let Ok(typ) = table_type |
| 114 | + && let LuaType::Array(array_type) = typ |
| 115 | + { |
| 116 | + return Some(vec![array_type.get_base().clone()]); |
| 117 | + } |
66 | 118 | } |
67 | | - LuaAst::LuaAssignStat(_) => {} |
68 | 119 | LuaAst::LuaTableField(table_field) => { |
69 | 120 | let typ = infer_table_field_value_should_be( |
70 | 121 | builder.semantic_model.get_db(), |
|
0 commit comments