Fix assoc function symbols
This commit is contained in:
		
							parent
							
								
									9b9baabc81
								
							
						
					
					
						commit
						1ae164b1d6
					
				| @ -22,6 +22,8 @@ fn main() -> u32 { | ||||
|     let otus = Otus { field: 17 }; | ||||
|     print(from_str("otus: ") + otus.test() as u64); | ||||
| 
 | ||||
|     otus.field; | ||||
| 
 | ||||
| 
 | ||||
|     return otus.test(); | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,11 @@ pub const TOKEN_LEGEND: [SemanticTokenType; 9] = [ | ||||
| 
 | ||||
| const SEMANTIC_REFERENCE: SemanticTokenModifier = SemanticTokenModifier::new("reference"); | ||||
| 
 | ||||
| pub const MODIFIER_LEGEND: [SemanticTokenModifier; 2] = [SemanticTokenModifier::DEFINITION, SEMANTIC_REFERENCE]; | ||||
| pub const MODIFIER_LEGEND: [SemanticTokenModifier; 3] = [ | ||||
|     SemanticTokenModifier::DEFINITION, | ||||
|     SEMANTIC_REFERENCE, | ||||
|     SemanticTokenModifier::DECLARATION, | ||||
| ]; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct StaticAnalysis { | ||||
| @ -156,6 +160,7 @@ pub struct AnalysisScope<'a> { | ||||
|     variables: HashMap<String, SymbolId>, | ||||
|     functions: HashMap<String, SymbolId>, | ||||
|     associated_functions: HashMap<(TypeKind, String), SymbolId>, | ||||
|     properties: HashMap<(TypeKind, String), SymbolId>, | ||||
|     types: HashMap<TypeKind, SymbolId>, | ||||
| } | ||||
| 
 | ||||
| @ -167,6 +172,7 @@ impl<'a> AnalysisScope<'a> { | ||||
|             variables: self.variables.clone(), | ||||
|             functions: self.functions.clone(), | ||||
|             associated_functions: self.associated_functions.clone(), | ||||
|             properties: self.properties.clone(), | ||||
|             types: self.types.clone(), | ||||
|         } | ||||
|     } | ||||
| @ -240,7 +246,7 @@ impl SemanticKind { | ||||
|             SemanticKind::String => return None, | ||||
|             SemanticKind::Number => return None, | ||||
|             SemanticKind::Default => return None, | ||||
|             SemanticKind::Property => return None, | ||||
|             SemanticKind::Property => SemanticTokenModifier::DECLARATION, | ||||
|             SemanticKind::Struct => SemanticTokenModifier::DEFINITION, | ||||
|             SemanticKind::Comment => return None, | ||||
|             SemanticKind::Operator => return None, | ||||
| @ -300,6 +306,7 @@ pub fn analyze_context(context: &mir::Context, module: &mir::Module, error: Opti | ||||
|         variables: HashMap::new(), | ||||
|         functions: HashMap::new(), | ||||
|         associated_functions: HashMap::new(), | ||||
|         properties: HashMap::new(), | ||||
|         types: HashMap::new(), | ||||
|     }; | ||||
|     for import in &module.imports { | ||||
| @ -344,19 +351,37 @@ pub fn analyze_context(context: &mir::Context, module: &mir::Module, error: Opti | ||||
|     } | ||||
| 
 | ||||
|     for typedef in &module.typedefs { | ||||
|         if typedef.source_module != module.module_id { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         match &typedef.kind { | ||||
|             mir::TypeDefinitionKind::Struct(StructType(fields)) => { | ||||
|                 let idx = scope | ||||
|                 let struct_idx = scope | ||||
|                     .token_idx(&typedef.meta, |t| matches!(t, Token::Identifier(_))) | ||||
|                     .unwrap_or(typedef.meta.range.end); | ||||
|                 let symbol = scope.state.new_symbol(idx, SemanticKind::Struct); | ||||
|                 scope.state.set_symbol(idx, symbol); | ||||
|                 let struct_symbol = scope.state.new_symbol(struct_idx, SemanticKind::Struct); | ||||
|                 scope.state.set_symbol(struct_idx, struct_symbol); | ||||
|                 scope.types.insert( | ||||
|                     TypeKind::CustomType(CustomTypeKey(typedef.name.clone(), typedef.source_module)), | ||||
|                     symbol, | ||||
|                     struct_symbol, | ||||
|                 ); | ||||
| 
 | ||||
|                 for field in fields { | ||||
|                     let field_idx = scope | ||||
|                         .token_idx(&field.2, |t| matches!(t, Token::Identifier(_))) | ||||
|                         .unwrap_or(field.2.range.end); | ||||
|                     let field_symbol = scope.state.new_symbol(field_idx, SemanticKind::Property); | ||||
|                     scope.state.set_symbol(field_idx, field_symbol); | ||||
| 
 | ||||
|                     scope.properties.insert( | ||||
|                         ( | ||||
|                             TypeKind::CustomType(CustomTypeKey(typedef.name.clone(), typedef.source_module)), | ||||
|                             field.0.clone(), | ||||
|                         ), | ||||
|                         field_symbol, | ||||
|                     ); | ||||
| 
 | ||||
|                     scope.state.init_types(&field.2, Some(field.1.clone())); | ||||
|                 } | ||||
|             } | ||||
| @ -524,7 +549,6 @@ pub fn analyze_expr( | ||||
|                 scope.state.new_symbol(idx, SemanticKind::Type) | ||||
|             }; | ||||
|             scope.state.set_symbol(idx, symbol); | ||||
|             scope.variables.insert(var_ref.1.clone(), symbol); | ||||
|         } | ||||
|         mir::ExprKind::Indexed(value, _, index_expr) => { | ||||
|             analyze_expr(context, source_module, &value, scope); | ||||
| @ -533,12 +557,6 @@ pub fn analyze_expr( | ||||
|         mir::ExprKind::Accessed(expression, _, name, meta) => { | ||||
|             analyze_expr(context, source_module, &expression, scope); | ||||
| 
 | ||||
|             let idx = scope | ||||
|                 .token_idx(&meta, |t| matches!(t, Token::Identifier(_))) | ||||
|                 .unwrap_or(meta.range.end); | ||||
|             let symbol = scope.state.new_symbol(idx, SemanticKind::Property); | ||||
|             scope.state.set_symbol(idx, symbol); | ||||
| 
 | ||||
|             let accessed_type = expression.return_type(&TypeRefs::unknown(), source_module.module_id); | ||||
| 
 | ||||
|             let mut autocompletes = Vec::new(); | ||||
| @ -554,12 +572,24 @@ pub fn analyze_expr( | ||||
|                                 kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()), | ||||
|                             }), | ||||
|                     ); | ||||
|                     match accessed_type { | ||||
|                     match &accessed_type { | ||||
|                         TypeKind::CustomType(ty_key) => { | ||||
|                             let typedef = source_module | ||||
|                                 .typedefs | ||||
|                                 .iter() | ||||
|                                 .find(|t| t.name == ty_key.0 && t.source_module == ty_key.1); | ||||
| 
 | ||||
|                             let field_idx = scope | ||||
|                                 .token_idx(&meta, |t| matches!(t, Token::Identifier(_))) | ||||
|                                 .unwrap_or(meta.range.end); | ||||
|                             let field_symbol = | ||||
|                                 if let Some(symbol_id) = scope.properties.get(&(accessed_type.clone(), name.clone())) { | ||||
|                                     scope.state.new_symbol(field_idx, SemanticKind::Reference(*symbol_id)) | ||||
|                                 } else { | ||||
|                                     scope.state.new_symbol(field_idx, SemanticKind::Property) | ||||
|                                 }; | ||||
|                             scope.state.set_symbol(field_idx, field_symbol); | ||||
| 
 | ||||
|                             if let Some(typedef) = typedef { | ||||
|                                 autocompletes.extend(match &typedef.kind { | ||||
|                                     mir::TypeDefinitionKind::Struct(StructType(fields)) => { | ||||
| @ -643,7 +673,13 @@ pub fn analyze_expr( | ||||
|             let type_idx = scope | ||||
|                 .token_idx(&expr.1, |t| matches!(t, Token::Identifier(_))) | ||||
|                 .unwrap_or(expr.1.range.end); | ||||
|             let type_symbol = if let Some(symbol_id) = scope.types.get(&ty) { | ||||
|             let invoked_ty = if let TypeKind::Borrow(inner, _) = ty { | ||||
|                 *inner.clone() | ||||
|             } else { | ||||
|                 ty.clone() | ||||
|             }; | ||||
| 
 | ||||
|             let type_symbol = if let Some(symbol_id) = scope.types.get(&invoked_ty) { | ||||
|                 scope.state.new_symbol(type_idx, SemanticKind::Reference(*symbol_id)) | ||||
|             } else { | ||||
|                 scope.state.new_symbol(type_idx, SemanticKind::Type) | ||||
| @ -653,7 +689,8 @@ pub fn analyze_expr( | ||||
|             let fn_idx = scope | ||||
|                 .token_idx(&meta, |t| matches!(t, Token::Identifier(_))) | ||||
|                 .unwrap_or(meta.range.end); | ||||
|             let fn_symbol = if let Some(symbol_id) = scope.associated_functions.get(&(ty.clone(), name.clone())) { | ||||
|             let fn_symbol = if let Some(symbol_id) = scope.associated_functions.get(&(invoked_ty.clone(), name.clone())) | ||||
|             { | ||||
|                 scope.state.new_symbol(fn_idx, SemanticKind::Reference(*symbol_id)) | ||||
|             } else { | ||||
|                 scope.state.new_symbol(fn_idx, SemanticKind::Function) | ||||
| @ -666,14 +703,14 @@ pub fn analyze_expr( | ||||
|             let mut function_autocomplete = source_module | ||||
|                 .associated_functions | ||||
|                 .iter() | ||||
|                 .filter(|(t, fun)| t == ty && fun.name.starts_with(name)) | ||||
|                 .filter(|(t, fun)| *t == invoked_ty && fun.name.starts_with(name)) | ||||
|                 .map(|(_, fun)| Autocomplete { | ||||
|                     text: fun.name.clone(), | ||||
|                     kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()), | ||||
|                 }) | ||||
|                 .collect::<Vec<_>>(); | ||||
|             function_autocomplete.extend( | ||||
|                 get_intrinsic_assoc_functions(ty) | ||||
|                 get_intrinsic_assoc_functions(&invoked_ty) | ||||
|                     .iter() | ||||
|                     .filter_map(|(s, f)| f.as_ref().map(|f| (s, f))) | ||||
|                     .filter(|(_, fun)| fun.name.starts_with(name)) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user