Fix token-ranges for derefs and binop rhs

This commit is contained in:
Sofia 2025-08-04 14:30:36 +03:00
parent 28157ae4b8
commit 79ecb3b9ba
5 changed files with 53 additions and 17 deletions

View File

@ -76,7 +76,6 @@ export function activate(context: ExtensionContext) {
scheme: 'file' scheme: 'file'
}, { }, {
provideDocumentSemanticTokens: () => { provideDocumentSemanticTokens: () => {
client.info("hello!");
const builder = new SemanticTokensBuilder(); const builder = new SemanticTokensBuilder();
return builder.build(); return builder.build();
} }

View File

@ -626,24 +626,34 @@ pub fn analyze_context(
scope scope
.associated_functions .associated_functions
.insert((ty.clone(), function.name.clone()), (module.module_id, symbol)); .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 { for param in &function.parameters {
scope.state.init_types(&param.meta, Some(param.ty.clone())); inner_scope.state.init_types(&param.meta, Some(param.ty.clone()));
if param.meta.source_module_id == module.module_id { if param.meta.source_module_id == module.module_id {
let param_idx = scope let param_idx = inner_scope
.token_idx(&param.meta, |t| matches!(t, Token::Identifier(_))) .token_idx(&param.meta, |t| matches!(t, Token::Identifier(_)))
.unwrap_or(function.signature().range.end); .unwrap_or(function.signature().range.end);
let param_symbol = scope let param_symbol = inner_scope
.state .state
.new_symbol(param_idx, SemanticKind::Variable, module.module_id); .new_symbol(param_idx, SemanticKind::Variable, module.module_id);
scope.state.set_symbol(param_idx, param_symbol); inner_scope.state.set_symbol(param_idx, param_symbol);
scope.variables.insert(param.name.clone(), param_symbol); inner_scope.variables.insert(param.name.clone(), param_symbol);
} }
} }
match &function.kind { 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::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {}
}; };
@ -677,20 +687,30 @@ pub fn analyze_context(
} }
for function in &module.functions { 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 { for param in &function.parameters {
scope.state.init_types(&param.meta, Some(param.ty.clone())); inner_scope.state.init_types(&param.meta, Some(param.ty.clone()));
if param.meta.source_module_id == module.module_id { if param.meta.source_module_id == module.module_id {
let idx = scope let idx = inner_scope
.token_idx(&param.meta, |t| matches!(t, Token::Identifier(_))) .token_idx(&param.meta, |t| matches!(t, Token::Identifier(_)))
.unwrap_or(function.signature().range.end); .unwrap_or(function.signature().range.end);
let symbol = scope.state.new_symbol(idx, SemanticKind::Variable, module.module_id); let symbol = inner_scope
scope.state.set_symbol(idx, symbol); .state
scope.variables.insert(param.name.clone(), symbol); .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 { 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::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {}
}; };

View File

@ -95,7 +95,7 @@ impl LanguageServer for Backend {
async fn initialized(&self, _: InitializedParams) { async fn initialized(&self, _: InitializedParams) {
self.client self.client
.log_message(MessageType::INFO, "Reid Language Server initialized hello!") .log_message(MessageType::INFO, "Reid Language Server initialized!")
.await; .await;
} }

View File

@ -287,9 +287,9 @@ impl Parse for PrimaryExpression {
stream.get_range().unwrap(), stream.get_range().unwrap(),
) )
} else if let Some(Token::Star) = stream.peek() { } else if let Some(Token::Star) = stream.peek() {
stream.next(); // Consume Et stream.next(); // Consume Star
apply_inner(stream.parse()?, |e| { 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() { } else if let Ok(unary) = stream.parse() {
Expression( Expression(
@ -510,7 +510,7 @@ fn parse_binop_rhs(
if curr_token_prec < next_prec { if curr_token_prec < next_prec {
// Operator on the right of rhs has more precedence, turn // Operator on the right of rhs has more precedence, turn
// rhs into lhs for new binop // 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 { } else {
let _ = prev_operator.insert(next_op); let _ = prev_operator.insert(next_op);
} }

View File

@ -199,6 +199,23 @@ impl<'a, 'b> TokenStream<'a, 'b> {
} }
} }
pub fn parse_with<T, U>(&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<TokenRange> { pub fn get_range(&self) -> Option<TokenRange> {
self.ref_position.as_ref().map(|ref_pos| TokenRange { self.ref_position.as_ref().map(|ref_pos| TokenRange {
start: **ref_pos, start: **ref_pos,