Check if a super() call can be optimized Returns Some(SuperCallType) if optimization is possible, None otherwise
(
&self,
value: &'a ast::Expr,
attr: &str,
)
| 898 | /// Check if a super() call can be optimized |
| 899 | /// Returns Some(SuperCallType) if optimization is possible, None otherwise |
| 900 | fn can_optimize_super_call<'a>( |
| 901 | &self, |
| 902 | value: &'a ast::Expr, |
| 903 | attr: &str, |
| 904 | ) -> Option<SuperCallType<'a>> { |
| 905 | // 1. value must be a Call expression |
| 906 | let ast::Expr::Call(ast::ExprCall { |
| 907 | func, arguments, .. |
| 908 | }) = value |
| 909 | else { |
| 910 | return None; |
| 911 | }; |
| 912 | |
| 913 | // 2. func must be Name("super") |
| 914 | let ast::Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else { |
| 915 | return None; |
| 916 | }; |
| 917 | if id.as_str() != "super" { |
| 918 | return None; |
| 919 | } |
| 920 | |
| 921 | // 3. attr must not be "__class__" |
| 922 | if attr == "__class__" { |
| 923 | return None; |
| 924 | } |
| 925 | |
| 926 | // 4. No keyword arguments |
| 927 | if !arguments.keywords.is_empty() { |
| 928 | return None; |
| 929 | } |
| 930 | |
| 931 | // 5. Must be inside a function (not at module level or class body) |
| 932 | if !self.ctx.in_func() { |
| 933 | return None; |
| 934 | } |
| 935 | |
| 936 | // 6. "super" must be GlobalImplicit (not redefined locally or at module level) |
| 937 | let table = self.current_symbol_table(); |
| 938 | if let Some(symbol) = table.lookup("super") |
| 939 | && symbol.scope != SymbolScope::GlobalImplicit |
| 940 | { |
| 941 | return None; |
| 942 | } |
| 943 | // Also check top-level scope to detect module-level shadowing. |
| 944 | // Only block if super is actually *bound* at module level (not just used). |
| 945 | if let Some(top_table) = self.symbol_table_stack.first() |
| 946 | && let Some(sym) = top_table.lookup("super") |
| 947 | && sym.scope != SymbolScope::GlobalImplicit |
| 948 | { |
| 949 | return None; |
| 950 | } |
| 951 | |
| 952 | // 7. Check argument pattern |
| 953 | let args = &arguments.args; |
| 954 | |
| 955 | // No starred expressions allowed |
| 956 | if args.iter().any(|arg| matches!(arg, ast::Expr::Starred(_))) { |
| 957 | return None; |