From 79ecb3b9bae618cee8310ec50a888823ac88fa43 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 4 Aug 2025 14:30:36 +0300 Subject: [PATCH] Fix token-ranges for derefs and binop rhs --- reid-lsp/client/src/extension.ts | 1 - reid-lsp/src/analysis.rs | 44 +++++++++++++++++++++++--------- reid-lsp/src/main.rs | 2 +- reid/src/ast/parse.rs | 6 ++--- reid/src/ast/token_stream.rs | 17 ++++++++++++ 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/reid-lsp/client/src/extension.ts b/reid-lsp/client/src/extension.ts index 7e42cd4..1e8b780 100644 --- a/reid-lsp/client/src/extension.ts +++ b/reid-lsp/client/src/extension.ts @@ -76,7 +76,6 @@ export function activate(context: ExtensionContext) { scheme: 'file' }, { provideDocumentSemanticTokens: () => { - client.info("hello!"); const builder = new SemanticTokensBuilder(); return builder.build(); } diff --git a/reid-lsp/src/analysis.rs b/reid-lsp/src/analysis.rs index c0a45fa..e7f076b 100644 --- a/reid-lsp/src/analysis.rs +++ b/reid-lsp/src/analysis.rs @@ -626,24 +626,34 @@ pub fn analyze_context( scope .associated_functions .insert((ty.clone(), function.name.clone()), (module.module_id, symbol)); + } + + for (_, function) in &module.associated_functions { + if let Some(source_id) = function.source { + if source_id != module.module_id { + continue; + } + } + + let mut inner_scope = scope.inner(); for param in &function.parameters { - scope.state.init_types(¶m.meta, Some(param.ty.clone())); + inner_scope.state.init_types(¶m.meta, Some(param.ty.clone())); if param.meta.source_module_id == module.module_id { - let param_idx = scope + let param_idx = inner_scope .token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_))) .unwrap_or(function.signature().range.end); - let param_symbol = scope + let param_symbol = inner_scope .state .new_symbol(param_idx, SemanticKind::Variable, module.module_id); - scope.state.set_symbol(param_idx, param_symbol); - scope.variables.insert(param.name.clone(), param_symbol); + inner_scope.state.set_symbol(param_idx, param_symbol); + inner_scope.variables.insert(param.name.clone(), param_symbol); } } match &function.kind { - mir::FunctionDefinitionKind::Local(block, _) => analyze_block(context, module, block, &mut scope), + mir::FunctionDefinitionKind::Local(block, _) => analyze_block(context, module, block, &mut inner_scope), mir::FunctionDefinitionKind::Extern(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {} }; @@ -677,20 +687,30 @@ pub fn analyze_context( } for function in &module.functions { + if let Some(source_id) = function.source { + if source_id != module.module_id { + continue; + } + } + + let mut inner_scope = scope.inner(); + for param in &function.parameters { - scope.state.init_types(¶m.meta, Some(param.ty.clone())); + inner_scope.state.init_types(¶m.meta, Some(param.ty.clone())); if param.meta.source_module_id == module.module_id { - let idx = scope + let idx = inner_scope .token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_))) .unwrap_or(function.signature().range.end); - let symbol = scope.state.new_symbol(idx, SemanticKind::Variable, module.module_id); - scope.state.set_symbol(idx, symbol); - scope.variables.insert(param.name.clone(), symbol); + let symbol = inner_scope + .state + .new_symbol(idx, SemanticKind::Variable, module.module_id); + inner_scope.state.set_symbol(idx, symbol); + inner_scope.variables.insert(param.name.clone(), symbol); } } match &function.kind { - mir::FunctionDefinitionKind::Local(block, _) => analyze_block(context, module, block, &mut scope), + mir::FunctionDefinitionKind::Local(block, _) => analyze_block(context, module, block, &mut inner_scope), mir::FunctionDefinitionKind::Extern(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {} }; diff --git a/reid-lsp/src/main.rs b/reid-lsp/src/main.rs index a877eae..79108ae 100644 --- a/reid-lsp/src/main.rs +++ b/reid-lsp/src/main.rs @@ -95,7 +95,7 @@ impl LanguageServer for Backend { async fn initialized(&self, _: InitializedParams) { self.client - .log_message(MessageType::INFO, "Reid Language Server initialized hello!") + .log_message(MessageType::INFO, "Reid Language Server initialized!") .await; } diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 43fd7f7..ec1f78a 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -287,9 +287,9 @@ impl Parse for PrimaryExpression { stream.get_range().unwrap(), ) } else if let Some(Token::Star) = stream.peek() { - stream.next(); // Consume Et + stream.next(); // Consume Star apply_inner(stream.parse()?, |e| { - Expression(Kind::Deref(Box::new(e.0)), stream.get_range().unwrap()) + Expression(Kind::Deref(Box::new(e.0.clone())), e.0 .1) }) } else if let Ok(unary) = stream.parse() { Expression( @@ -510,7 +510,7 @@ fn parse_binop_rhs( if curr_token_prec < next_prec { // Operator on the right of rhs has more precedence, turn // rhs into lhs for new binop - rhs = parse_binop_rhs(stream, rhs, Some(op))?; + rhs = stream.parse_with(|mut st| parse_binop_rhs(&mut st, rhs, Some(op)))?; } else { let _ = prev_operator.insert(next_op); } diff --git a/reid/src/ast/token_stream.rs b/reid/src/ast/token_stream.rs index a139398..89f5c48 100644 --- a/reid/src/ast/token_stream.rs +++ b/reid/src/ast/token_stream.rs @@ -199,6 +199,23 @@ impl<'a, 'b> TokenStream<'a, 'b> { } } + pub fn parse_with(&mut self, fun: T) -> U + where + T: FnOnce(TokenStream) -> U, + { + let mut ref_pos = self.position; + + let position = self.position; + let clone = TokenStream { + ref_position: Some(&mut ref_pos), + tokens: self.tokens, + errors: self.errors.clone(), + position, + }; + + fun(clone) + } + pub fn get_range(&self) -> Option { self.ref_position.as_ref().map(|ref_pos| TokenRange { start: **ref_pos,