Enter a new scope = compiler_enter_scope
(
&mut self,
name: &str,
scope_type: CompilerScope,
key: usize, // In RustPython, we use the index in symbol_table_stack as key
lineno: u32,
)
| 1060 | /// Enter a new scope |
| 1061 | // = compiler_enter_scope |
| 1062 | fn enter_scope( |
| 1063 | &mut self, |
| 1064 | name: &str, |
| 1065 | scope_type: CompilerScope, |
| 1066 | key: usize, // In RustPython, we use the index in symbol_table_stack as key |
| 1067 | lineno: u32, |
| 1068 | ) -> CompileResult<()> { |
| 1069 | // Allocate a new compiler unit |
| 1070 | |
| 1071 | // In Rust, we'll create the structure directly |
| 1072 | let source_path = self.source_file.name().to_owned(); |
| 1073 | |
| 1074 | // Lookup symbol table entry using key (_PySymtable_Lookup) |
| 1075 | let ste = match self.symbol_table_stack.get(key) { |
| 1076 | Some(v) => v, |
| 1077 | None => { |
| 1078 | return Err(self.error(CodegenErrorType::SyntaxError( |
| 1079 | "unknown symbol table entry".to_owned(), |
| 1080 | ))); |
| 1081 | } |
| 1082 | }; |
| 1083 | |
| 1084 | // Use varnames from symbol table (already collected in definition order) |
| 1085 | let varname_cache: IndexSet<String> = ste.varnames.iter().cloned().collect(); |
| 1086 | |
| 1087 | // Build cellvars using dictbytype (CELL scope or COMP_CELL flag, sorted) |
| 1088 | let mut cellvar_cache = IndexSet::default(); |
| 1089 | // CPython ordering: parameter cells first (in parameter order), |
| 1090 | // then non-parameter cells (alphabetically sorted) |
| 1091 | let cell_symbols: Vec<_> = ste |
| 1092 | .symbols |
| 1093 | .iter() |
| 1094 | .filter(|(_, s)| { |
| 1095 | s.scope == SymbolScope::Cell || s.flags.contains(SymbolFlags::COMP_CELL) |
| 1096 | }) |
| 1097 | .map(|(name, sym)| (name.clone(), sym.flags)) |
| 1098 | .collect(); |
| 1099 | let mut param_cells = Vec::new(); |
| 1100 | let mut nonparam_cells = Vec::new(); |
| 1101 | for (name, flags) in cell_symbols { |
| 1102 | if flags.contains(SymbolFlags::PARAMETER) { |
| 1103 | param_cells.push(name); |
| 1104 | } else { |
| 1105 | nonparam_cells.push(name); |
| 1106 | } |
| 1107 | } |
| 1108 | // param_cells are already in parameter order (from varname_cache insertion order) |
| 1109 | param_cells.sort_by_key(|n| varname_cache.get_index_of(n.as_str()).unwrap_or(usize::MAX)); |
| 1110 | nonparam_cells.sort(); |
| 1111 | for name in param_cells { |
| 1112 | cellvar_cache.insert(name); |
| 1113 | } |
| 1114 | for name in nonparam_cells { |
| 1115 | cellvar_cache.insert(name); |
| 1116 | } |
| 1117 | |
| 1118 | // Handle implicit __class__ cell if needed |
| 1119 | if ste.needs_class_closure { |
no test coverage detected