Skip to content

Commit 1a34efe

Browse files
mmahroussfda-odoo
authored andcommitted
[FIX] server: detect cycles on evaluating assignment stmts
1 parent 41611d7 commit 1a34efe

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

server/src/core/python_arch_eval.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{u32, vec};
66
use ruff_text_size::{Ranged, TextRange, TextSize};
77
use ruff_python_ast::{Alias, Expr, Identifier, Stmt, StmtAnnAssign, StmtAssign, StmtClassDef, StmtExpr, StmtFor, StmtFunctionDef, StmtIf, StmtReturn, StmtTry, StmtWhile, StmtWith};
88
use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString, Position, Range};
9-
use tracing::{debug, trace};
9+
use tracing::{debug, trace, warn};
1010

1111
use crate::constants::*;
1212
use crate::core::import_resolver::resolve_import_stmt;
@@ -306,20 +306,26 @@ impl PythonArchEval {
306306
if let Some(variable_rc) = variable {
307307
let parent = variable_rc.borrow().parent().unwrap().upgrade().unwrap().clone();
308308
if assign.annotation.is_some() {
309-
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.annotation.as_ref().unwrap(), parent, &ann_assign_stmt.range.start());
309+
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.annotation.as_ref().unwrap(), parent.clone(), &ann_assign_stmt.range.start());
310310
variable_rc.borrow_mut().set_evaluations(eval);
311311
self.diagnostics.extend(diags);
312312
} else if assign.value.is_some() {
313-
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.value.as_ref().unwrap(), parent, &ann_assign_stmt.range.start());
313+
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.value.as_ref().unwrap(), parent.clone(), &ann_assign_stmt.range.start());
314314
variable_rc.borrow_mut().set_evaluations(eval);
315315
self.diagnostics.extend(diags);
316316
} else {
317317
panic!("either value or annotation should exists");
318318
}
319319
let mut dep_to_add = vec![];
320-
let v_mut = variable_rc.borrow_mut();
321-
for evaluation in v_mut.evaluations().unwrap().iter() {
320+
let mut evals_to_drop: Vec<usize> = vec![];
321+
for (ix, evaluation) in variable_rc.borrow().evaluations().unwrap().iter().enumerate() {
322322
if let Some(sym) = evaluation.symbol.get_symbol_as_weak(session, &mut None, &mut self.diagnostics, None).weak.upgrade() {
323+
if Rc::ptr_eq(&sym, &variable_rc){
324+
// TODO: investigate deps, and fix cyclic evals
325+
warn!("Found cyclic evaluation symbol: {}, parent: {}", sym.borrow().name(), parent.borrow().name());
326+
evals_to_drop.push(ix);
327+
continue;
328+
}
323329
if let Some(file) = sym.borrow().get_file().clone() {
324330
let sym_file = file.upgrade().unwrap().clone();
325331
if !Rc::ptr_eq(&self.file, &sym_file) {
@@ -335,7 +341,10 @@ impl PythonArchEval {
335341
}
336342
}
337343
}
338-
drop(v_mut);
344+
let mut v_mut = variable_rc.borrow_mut();
345+
for ix in evals_to_drop.into_iter(){
346+
v_mut.evaluations_mut().unwrap().remove(ix);
347+
}
339348
for dep in dep_to_add {
340349
self.file.borrow_mut().add_dependency(&mut dep.borrow_mut(), self.current_step, BuildSteps::ARCH);
341350
}
@@ -351,13 +360,19 @@ impl PythonArchEval {
351360
let variable = self.sym_stack.last().unwrap().borrow_mut().get_positioned_symbol(&assign.target.id.to_string(), &assign.target.range);
352361
if let Some(variable_rc) = variable {
353362
let parent = variable_rc.borrow().parent().as_ref().unwrap().upgrade().unwrap().clone();
354-
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.value.as_ref().unwrap(), parent, &assign_stmt.range.start());
363+
let (eval, diags) = Evaluation::eval_from_ast(session, &assign.value.as_ref().unwrap(), parent.clone(), &assign_stmt.range.start());
355364
variable_rc.borrow_mut().set_evaluations(eval);
356365
self.diagnostics.extend(diags);
357366
let mut dep_to_add = vec![];
358-
let v_mut = variable_rc.borrow_mut();
359-
for evaluation in v_mut.evaluations().unwrap().iter() {
367+
let mut evals_to_drop: Vec<usize> = vec![];
368+
for (ix, evaluation) in variable_rc.borrow().evaluations().unwrap().iter().enumerate() {
360369
if let Some(sym) = evaluation.symbol.get_symbol_as_weak(session, &mut None, &mut self.diagnostics, None).weak.upgrade() {
370+
if Rc::ptr_eq(&sym, &variable_rc){
371+
// TODO: investigate deps, and fix cyclic evals
372+
warn!("Found cyclic evaluation symbol: {}, parent: {}", sym.borrow().name(), parent.borrow().name());
373+
evals_to_drop.push(ix);
374+
continue;
375+
}
361376
if let Some(file) = sym.borrow().get_file().clone() {
362377
let sym_file = file.upgrade().unwrap().clone();
363378
if !Rc::ptr_eq(&self.file, &sym_file) {
@@ -373,7 +388,10 @@ impl PythonArchEval {
373388
}
374389
}
375390
}
376-
drop(v_mut);
391+
let mut v_mut = variable_rc.borrow_mut();
392+
for ix in evals_to_drop.into_iter(){
393+
v_mut.evaluations_mut().unwrap().remove(ix);
394+
}
377395
for dep in dep_to_add {
378396
self.file.borrow_mut().add_dependency(&mut dep.borrow_mut(), self.current_step, BuildSteps::ARCH);
379397
}

0 commit comments

Comments
 (0)