WIP: submodule resolution bug

This commit is contained in:
Shunsuke Shibayama 2023-12-25 02:14:33 +09:00
parent 1b824d78e1
commit 26c758e67f
11 changed files with 169 additions and 37 deletions

View file

@ -2654,7 +2654,7 @@ impl Context {
if let Some(ctx) = self.get_nominal_type_ctx(sup) {
sup_ctxs.push(ctx);
} else if DEBUG_MODE {
todo!("no ctx for {sup}");
todo!("no ctx ({} / {}) for {sup}", self.name, self.kind);
}
}
Some(vec![ctx].into_iter().chain(sup_ctxs))

View file

@ -61,8 +61,6 @@ pub trait ContextProvider {
}
}
const BUILTINS: &Str = &Str::ever("<builtins>");
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ControlKind {
If,
@ -1140,10 +1138,8 @@ impl Context {
// NOTE: this need to be changed if we want to support nested classes/traits
if let Some(outer) = self.get_outer() {
outer.path()
} else if self.kind == ContextKind::Module {
self.name.replace(".__init__", "").into()
} else {
BUILTINS.clone()
self.name.replace(".__init__", "").into()
}
}
@ -1151,7 +1147,7 @@ impl Context {
/// This avoids infinite loops.
pub(crate) fn get_builtins(&self) -> Option<&Context> {
// builtins中で定義した型等はmod_cacheがNoneになっている
if self.kind != ContextKind::Module || &self.path()[..] != "<builtins>" {
if &self.path()[..] != "<builtins>" {
self.shared
.as_ref()
.map(|shared| {
@ -1175,7 +1171,13 @@ impl Context {
outer.get_module()
}
})
.or(Some(self))
.or_else(|| {
if self.kind == ContextKind::Module {
Some(self)
} else {
None
}
})
}
pub(crate) fn get_module_from_stack(&self, path: &NormalizedPathBuf) -> Option<&Context> {
@ -1249,10 +1251,10 @@ impl Context {
self.params.retain(|(_, v)| v.t != Failure);
}
/// Note that the popped context is detached and `outer == None`.
pub fn pop(&mut self) -> Context {
self.check_types();
if let Some(parent) = self.outer.as_mut() {
let parent = mem::take(parent);
if let Some(parent) = self.outer.take() {
let ctx = mem::take(self);
*self = *parent;
log!(info "{}: current namespace: {}", fn_name!(), self.name);

View file

@ -2513,6 +2513,30 @@ impl Context {
#[allow(clippy::single_match)]
match expr {
ast::Expr::Accessor(acc) => self.inc_ref_acc(acc, namespace, tmp_tv_cache),
ast::Expr::BinOp(bin) => {
self.inc_ref_expr(&bin.args[0], namespace, tmp_tv_cache)
|| self.inc_ref_expr(&bin.args[1], namespace, tmp_tv_cache)
}
ast::Expr::UnaryOp(unary) => self.inc_ref_expr(&unary.value(), namespace, tmp_tv_cache),
ast::Expr::Call(call) => {
let mut res = self.inc_ref_expr(&call.obj, namespace, tmp_tv_cache);
for arg in call.args.pos_args() {
if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
res = true;
}
}
if let Some(arg) = call.args.var_args() {
if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
res = true;
}
}
for arg in call.args.kw_args() {
if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
res = true;
}
}
res
}
ast::Expr::Record(ast::Record::Normal(rec)) => {
let mut res = false;
for val in rec.attrs.iter() {
@ -2522,10 +2546,6 @@ impl Context {
}
res
}
ast::Expr::BinOp(bin) => {
self.inc_ref_expr(&bin.args[0], namespace, tmp_tv_cache)
|| self.inc_ref_expr(&bin.args[1], namespace, tmp_tv_cache)
}
ast::Expr::Array(ast::Array::Normal(arr)) => {
let mut res = false;
for val in arr.elems.pos_args().iter() {
@ -2535,6 +2555,24 @@ impl Context {
}
res
}
ast::Expr::Tuple(ast::Tuple::Normal(tup)) => {
let mut res = false;
for val in tup.elems.pos_args().iter() {
if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
res = true;
}
}
res
}
ast::Expr::Set(ast::Set::Normal(set)) => {
let mut res = false;
for val in set.elems.pos_args().iter() {
if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
res = true;
}
}
res
}
ast::Expr::Set(ast::Set::Comprehension(comp)) => {
let mut res = false;
for (_, gen) in comp.generators.iter() {
@ -2549,6 +2587,32 @@ impl Context {
}
res
}
ast::Expr::Dict(ast::Dict::Normal(dict)) => {
let mut res = false;
for ast::KeyValue { key, value } in dict.kvs.iter() {
if self.inc_ref_expr(key, namespace, tmp_tv_cache) {
res = true;
}
if self.inc_ref_expr(value, namespace, tmp_tv_cache) {
res = true;
}
}
res
}
ast::Expr::Dict(ast::Dict::Comprehension(comp)) => {
let mut res = false;
for (_, gen) in comp.generators.iter() {
if self.inc_ref_expr(gen, namespace, tmp_tv_cache) {
res = true;
}
}
if let Some(guard) = &comp.guard {
if self.inc_ref_expr(guard, namespace, tmp_tv_cache) {
res = true;
}
}
res
}
other => {
log!(err "inc_ref_expr: {other}");
false