Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] server: use arena as memory allocator #154

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ tracing-panic = "0.1.2"
winapi = { version = "0.3.9", features = ["winbase", "processthreadsapi", "synchapi", "handleapi"] }
ctrlc = "3.4.4"
once_cell = "1.20.1"
generational-arena = "0.2.9"
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
nix = { version = "0.29.0", features = ["process"] }

Expand Down
270 changes: 140 additions & 130 deletions server/src/core/odoo.rs

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions server/src/core/python_arch_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::rc::Rc;
use std::cell::RefCell;
use std::vec;
use anyhow::Error;
use generational_arena::Index;
use ruff_text_size::{Ranged, TextRange};
use ruff_python_ast::{Alias, Expr, Identifier, Stmt, StmtAnnAssign, StmtAssign, StmtClassDef, StmtFor, StmtFunctionDef, StmtIf, StmtTry, StmtWith};
use lsp_types::Diagnostic;
Expand All @@ -26,16 +27,16 @@ use super::symbols::function_symbol::Argument;

#[derive(Debug)]
pub struct PythonArchBuilder {
file: Rc<RefCell<Symbol>>,
file: Index,
file_mode: bool,
current_step: BuildSteps,
sym_stack: Vec<Rc<RefCell<Symbol>>>,
sym_stack: Vec<Index>,
__all_symbols_to_add: Vec<(String, TextRange)>,
diagnostics: Vec<Diagnostic>
}

impl PythonArchBuilder {
pub fn new(symbol: Rc<RefCell<Symbol>>) -> PythonArchBuilder {
pub fn new(symbol: Index) -> PythonArchBuilder {
PythonArchBuilder {
file: symbol.clone(), //dummy, evaluated in load_arch
file_mode: false, //dummy, evaluated in load_arch
Expand Down
7 changes: 4 additions & 3 deletions server/src/core/python_arch_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::rc::Rc;
use std::cell::RefCell;
use std::{u32, vec};

use generational_arena::Index;
use ruff_text_size::{Ranged, TextRange};
use ruff_python_ast::{Alias, Expr, Identifier, Stmt, StmtAnnAssign, StmtAssign, StmtClassDef, StmtFor, StmtFunctionDef, StmtIf, StmtReturn, StmtTry, StmtWith};
use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString, Position, Range};
Expand Down Expand Up @@ -30,17 +31,17 @@ use super::symbols::function_symbol::FunctionSymbol;

#[derive(Debug, Clone)]
pub struct PythonArchEval {
file: Rc<RefCell<Symbol>>,
file: Index,
file_mode: bool,
current_step: BuildSteps,
sym_stack: Vec<Rc<RefCell<Symbol>>>,
sym_stack: Vec<Index>,
diagnostics: Vec<Diagnostic>,
safe_import: Vec<bool>,
ast_indexes: Vec<u16>,
}

impl PythonArchEval {
pub fn new(symbol: Rc<RefCell<Symbol>>) -> PythonArchEval {
pub fn new(symbol: Index) -> PythonArchEval {
PythonArchEval {
file: symbol.clone(), //dummy, evaluated in eval_arch
file_mode: false, //dummy, evaluated in eval_arch
Expand Down
5 changes: 3 additions & 2 deletions server/src/core/python_odoo_builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::PathBuf;
use std::rc::Rc;
use std::cell::RefCell;
use generational_arena::Index;
use lsp_types::notification::ShowMessage;
use lsp_types::MessageType;
use ruff_python_ast::Expr;
Expand All @@ -17,13 +18,13 @@ use crate::S;
use super::evaluation::EvaluationValue;

pub struct PythonOdooBuilder {
symbol: Rc<RefCell<Symbol>>,
symbol: Index,
diagnostics: Vec<Diagnostic>,
}

impl PythonOdooBuilder {

pub fn new(symbol: Rc<RefCell<Symbol>>) -> PythonOdooBuilder {
pub fn new(symbol: Index) -> PythonOdooBuilder {
PythonOdooBuilder {
symbol: symbol,
diagnostics: vec![]
Expand Down
7 changes: 4 additions & 3 deletions server/src/core/python_validator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use generational_arena::Index;
use ruff_python_ast::{Alias, Expr, Identifier, Stmt, StmtAnnAssign, StmtAssign, StmtClassDef, StmtTry};
use ruff_text_size::{Ranged, TextRange};
use tracing::{trace, warn};
Expand All @@ -23,17 +24,17 @@ use super::python_arch_eval::PythonArchEval;
#[derive(Debug)]
pub struct PythonValidator {
file_mode: bool,
sym_stack: Vec<Rc<RefCell<Symbol>>>,
sym_stack: Vec<Index>,
pub diagnostics: Vec<Diagnostic>, //collect diagnostic from arch and arch_eval too from inner functions, but put everything at Validation level
safe_imports: Vec<bool>,
current_module: Option<Rc<RefCell<Symbol>>>
current_module: Option<Index>
}

/* PythonValidator operate on a single Symbol. Unlike other steps, it can be done on symbol containing code (file and functions only. Not class, variable, namespace).
It will validate this node and run a validator on all subsymbol and dependencies.
It will try to inference the return type of functions if it is not annotated; */
impl PythonValidator {
pub fn new(symbol: Rc<RefCell<Symbol>>) -> Self {
pub fn new(symbol: Index) -> Self {
Self {
file_mode: true,
sym_stack: vec![symbol],
Expand Down
57 changes: 29 additions & 28 deletions server/src/core/symbols/file_symbol.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use generational_arena::Index;
use weak_table::PtrWeakHashSet;

use crate::{constants::{BuildStatus, BuildSteps}, core::model::Model};
use std::{cell::RefCell, collections::HashMap, rc::{Rc, Weak}};
use crate::{constants::{BuildStatus, BuildSteps}, core::model::Model, threads::SessionInfo};
use std::{cell::RefCell, collections::{HashMap, HashSet}, rc::{Rc, Weak}};

use super::{symbol::Symbol, symbol_mgr::{SectionRange, SymbolMgr}};

Expand All @@ -10,21 +11,21 @@ pub struct FileSymbol {
pub name: String,
pub path: String,
pub is_external: bool,
pub weak_self: Option<Weak<RefCell<Symbol>>>,
pub parent: Option<Weak<RefCell<Symbol>>>,
pub self_index: Option<Index>,
pub parent: Option<Index>,
pub arch_status: BuildStatus,
pub arch_eval_status: BuildStatus,
pub odoo_status: BuildStatus,
pub validation_status: BuildStatus,
pub not_found_paths: Vec<(BuildSteps, Vec<String>)>,
pub in_workspace: bool,
pub model_dependencies: PtrWeakHashSet<Weak<RefCell<Model>>>, //always on validation level, as odoo step is always required
pub dependencies: [Vec<PtrWeakHashSet<Weak<RefCell<Symbol>>>>; 4],
pub dependents: [Vec<PtrWeakHashSet<Weak<RefCell<Symbol>>>>; 3],
pub model_dependencies: HashSet<Index>, //always on validation level, as odoo step is always required
pub dependencies: [Vec<HashSet<Index>>; 4],
pub dependents: [Vec<HashSet<Index>>; 3],

//Trait SymbolMgr
pub sections: Vec<SectionRange>,
pub symbols: HashMap<String, HashMap<u32, Vec<Rc<RefCell<Symbol>>>>>,
pub symbols: HashMap<String, HashMap<u32, Vec<Index>>>,
//--- dynamics variables
pub ext_symbols: HashMap<String, Vec<Rc<RefCell<Symbol>>>>,
}
Expand All @@ -36,7 +37,7 @@ impl FileSymbol {
name,
path,
is_external,
weak_self: None,
self_index: None,
parent: None,
arch_status: BuildStatus::PENDING,
arch_eval_status: BuildStatus::PENDING,
Expand All @@ -47,46 +48,46 @@ impl FileSymbol {
sections: vec![],
symbols: HashMap::new(),
ext_symbols: HashMap::new(),
model_dependencies: PtrWeakHashSet::new(),
model_dependencies: HashSet::new(),
dependencies: [
vec![ //ARCH
PtrWeakHashSet::new() //ARCH
HashSet::new() //ARCH
],
vec![ //ARCH_EVAL
PtrWeakHashSet::new() //ARCH
HashSet::new() //ARCH
],
vec![
PtrWeakHashSet::new(), // ARCH
PtrWeakHashSet::new(), //ARCH_EVAL
PtrWeakHashSet::new() //ODOO
HashSet::new(), // ARCH
HashSet::new(), //ARCH_EVAL
HashSet::new() //ODOO
],
vec![
PtrWeakHashSet::new(), // ARCH
PtrWeakHashSet::new(), //ARCH_EVAL
PtrWeakHashSet::new() //ODOO
HashSet::new(), // ARCH
HashSet::new(), //ARCH_EVAL
HashSet::new() //ODOO
]],
dependents: [
vec![ //ARCH
PtrWeakHashSet::new(), //ARCH
PtrWeakHashSet::new(), //ARCH_EVAL
PtrWeakHashSet::new(), //ODOO
PtrWeakHashSet::new(), //VALIDATION
HashSet::new(), //ARCH
HashSet::new(), //ARCH_EVAL
HashSet::new(), //ODOO
HashSet::new(), //VALIDATION
],
vec![ //ARCH_EVAL
PtrWeakHashSet::new(), //ODOO
PtrWeakHashSet::new() //VALIDATION
HashSet::new(), //ODOO
HashSet::new() //VALIDATION
],
vec![ //ODOO
PtrWeakHashSet::new(), //ODOO
PtrWeakHashSet::new() //VALIDATION
HashSet::new(), //ODOO
HashSet::new() //VALIDATION
]],
};
res._init_symbol_mgr();
res
}

pub fn add_symbol(&mut self, content: &Rc<RefCell<Symbol>>, section: u32) {
let sections = self.symbols.entry(content.borrow().name().clone()).or_insert_with(|| HashMap::new());
pub fn add_symbol(&mut self, session: &mut SessionInfo, content: Index, section: u32) {
let sections = self.symbols.entry(session.get_sym(content).unwrap().name().clone()).or_insert_with(|| HashMap::new());
let section_vec = sections.entry(section).or_insert_with(|| vec![]);
section_vec.push(content.clone());
}
Expand Down
41 changes: 20 additions & 21 deletions server/src/core/symbols/module_symbol.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use generational_arena::Index;
use lsp_types::{Diagnostic, DiagnosticSeverity, DiagnosticTag, NumberOrString, Position, Range};
use ruff_python_ast::{Expr, Stmt};
use ruff_text_size::{Ranged, TextRange};
Expand Down Expand Up @@ -40,8 +41,8 @@ pub struct ModuleSymbol {
pub arch_eval_status: BuildStatus,
pub odoo_status: BuildStatus,
pub validation_status: BuildStatus,
pub weak_self: Option<Weak<RefCell<Symbol>>>,
pub parent: Option<Weak<RefCell<Symbol>>>,
pub self_index: Option<Index>,
pub parent: Option<Index>,
pub not_found_paths: Vec<(BuildSteps, Vec<String>)>,
pub in_workspace: bool,
pub model_dependencies: PtrWeakHashSet<Weak<RefCell<Model>>>, //always on validation level, as odoo step is always required
Expand Down Expand Up @@ -71,7 +72,7 @@ impl ModuleSymbol {
dir_name: String::new(),
depends: vec!("base".to_string()),
data: Vec::new(),
weak_self: None,
self_index: None,
parent: None,
module_symbols: HashMap::new(),
arch_status: BuildStatus::PENDING,
Expand Down Expand Up @@ -302,7 +303,7 @@ impl ModuleSymbol {
if !session.sync_odoo.modules.contains_key(depend) {
let module = find_module(session, odoo_addons.clone(), depend);
if module.is_none() {
session.sync_odoo.not_found_symbols.insert(symbol.weak_self().as_ref().unwrap().upgrade().expect("The symbol must be in the tree"));
session.sync_odoo.not_found_symbols.insert(symbol.self_index().as_ref().unwrap().clone());
symbol.not_found_paths_mut().push((BuildSteps::ARCH, vec![S!("odoo"), S!("addons"), depend.clone()]));
diagnostics.push(Diagnostic::new(
Range::new(Position::new(0, 0), Position::new(0, 1)),
Expand All @@ -320,52 +321,50 @@ impl ModuleSymbol {
symbol.add_dependency(&mut module, BuildSteps::ARCH, BuildSteps::ARCH);
}
} else {
let module = session.sync_odoo.modules.get(depend).unwrap().upgrade().unwrap();
let mut module = (*module).borrow_mut();
let mut module = session.get_sym_mut(session.sync_odoo.modules.get(depend).unwrap().clone()).unwrap();
symbol.add_dependency(&mut module, BuildSteps::ARCH, BuildSteps::ARCH)
}
}
(diagnostics, loaded)
}

fn _load_data(_symbol: Rc<RefCell<Symbol>>, _odoo: &mut SyncOdoo) -> Vec<Diagnostic> {
fn _load_data(_symbol: Index, _odoo: &mut SyncOdoo) -> Vec<Diagnostic> {
vec![]
}

fn _load_arch(symbol: Rc<RefCell<Symbol>>, session: &mut SessionInfo) -> Vec<Diagnostic> {
let root_path = (*symbol).borrow().as_module_package().root_path.clone();
fn _load_arch(symbol: Index, session: &mut SessionInfo) -> Vec<Diagnostic> {
let root_path = session.get_sym(symbol).unwrap().as_module_package().root_path.clone();
let tests_path = PathBuf::from(root_path).join("tests");
if tests_path.exists() {
let rc_symbol = Symbol::create_from_path(session, &tests_path, symbol, false);
if rc_symbol.is_some() && rc_symbol.as_ref().unwrap().borrow().typ() != SymType::NAMESPACE {
let rc_symbol = rc_symbol.unwrap();
session.sync_odoo.add_to_rebuild_arch(rc_symbol);
let symbol_idx = Symbol::create_from_path(session, &tests_path, symbol, false);
if symbol_idx.is_some() && session.get_sym(symbol_idx.unwrap()).unwrap().typ() != SymType::NAMESPACE {
let symbol_idx = symbol_idx.unwrap();
session.sync_odoo.add_to_rebuild_arch(symbol_idx);
}
}
vec![]
}

pub fn is_in_deps(session: &mut SessionInfo, symbol: &Rc<RefCell<Symbol>>, dir_name: &String, acc: &mut Option<HashSet<String>>) -> bool {
if symbol.borrow().as_module_package().dir_name == *dir_name || symbol.borrow().as_module_package().depends.contains(dir_name) {
pub fn is_in_deps(session: &mut SessionInfo, symbol: &Index, dir_name: &String, acc: &mut Option<HashSet<String>>) -> bool {
if session.get_sym(symbol.clone()).unwrap().as_module_package().dir_name == *dir_name || session.get_sym(symbol.clone()).unwrap().as_module_package().depends.contains(dir_name) {
return true;
}
if acc.is_none() {
*acc = Some(HashSet::new());
}
for dep in symbol.borrow().as_module_package().depends.iter() {
for dep in session.get_sym(symbol.clone()).unwrap().as_module_package().depends.clone().iter() {
if acc.as_ref().unwrap().contains(dep) {
continue;
}
let dep_module = session.sync_odoo.modules.get(dep);
let dep_module = session.sync_odoo.modules.get(dep).cloned();
if let Some(dep_module) = dep_module {
let dep_module = dep_module.upgrade();
if dep_module.is_none() {
if session.get_sym(dep_module.clone()).is_none() {
continue;
}
if ModuleSymbol::is_in_deps(session, dep_module.as_ref().unwrap(), dir_name, acc) {
if ModuleSymbol::is_in_deps(session, &dep_module, dir_name, acc) {
return true;
}
acc.as_mut().unwrap().insert(dep_module.as_ref().unwrap().borrow().as_module_package().dir_name.clone());
acc.as_mut().unwrap().insert(session.get_sym(dep_module.clone()).unwrap().as_module_package().dir_name.clone());
}
}
false
Expand Down
Loading