]> Nishi Git Mirror - gwion.git/commitdiff
:art: Ctor checking
authorfennecdjay <fennecdjay@gmail.com>
Sat, 19 Nov 2022 14:00:09 +0000 (15:00 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Sat, 19 Nov 2022 14:00:09 +0000 (15:00 +0100)
src/lib/object_op.c
src/parse/check.c

index 8ddf68bf906ac8d695d5af786ae6654ec960f5ab..b2a5c75810ec3070ec02c3ccd3f9a3f1edda3a88 100644 (file)
@@ -140,6 +140,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) {
     }
   } else if (is_static_call(emit->gwion, exp_self(member))) {
     if (member->is_call && f == emit->env->func && !is_new(f->def)) return;
+    if(!member->is_call) emit_regmove(emit, SZ_INT);
     return emit_pushfunc(emit, f);
   } else {
     if (tflag(member->base->type, tflag_struct))
@@ -210,8 +211,8 @@ OP_CHECK(opck_object_dot) {
         if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class) > 0)) // is_callable needs type
           return v->type;
         if (is_class(env->gwion, v->type)) {
-           DECL_OO(const Type, parent, = class_type(env, member, v->type));
-          if (isa(the_base, parent) > 0 && parent->nspc) {
+          DECL_OO(const Type, parent, = class_type(env, member, v->type));
+          if (the_base->info->parent == parent && parent->nspc) {
             const Symbol sym = insert_symbol(env->gwion->st, "new");
             if(!env->func || env->func->def->base->xid != sym)
               ERR_N(exp_self(member)->pos, "calling a parent constructor is only allowed in `new` definition");
@@ -228,8 +229,7 @@ OP_CHECK(opck_object_dot) {
             if(ret) return ret->type;
           }
         }
-      } else if(is_class(env->gwion, v->type) && the_base == v->type->info->base_type)
-        return v->type->info->base_type;
+      }
     }
     env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"),
             the_base->name, str);
index ee4afd8f7e86c69ec5a9900fac3d529066286b9d..82e43087afb27d726d437629b000beda5d277e78 100644 (file)
@@ -1782,6 +1782,31 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef,
   return GW_OK;
 }
 
+ANN static bool effect_find(const MP_Vector *v, const Symbol sym) {
+  for(m_uint i = 0; i < v->len; i++) {
+    struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
+    if(eff->sym == sym) return true;
+  }
+  return false;
+}
+
+ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
+  MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
+  if (v) {
+    if (fdef->base->xid == insert_symbol("@dtor"))
+      ERR_B(fdef->base->pos, _("can't use effects in destructors"));
+    const Vector base = &fdef->base->effects;
+    if (!base->ptr) vector_init(base);
+    for (uint32_t i = 0; i < v->len; i++) {
+      struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
+      if(!effect_find(v, eff->sym))
+        vector_add(base, (m_uint)eff->sym);
+    }
+    free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
+  }
+  return GW_OK;
+}
+
 ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
   if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args));
   if(fdef->builtin) return GW_OK;
@@ -1791,17 +1816,16 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
     const m_bool ret = check_stmt_list(env, fdef->d.code);
     nspc_pop_value(env->gwion->mp, env->curr);
     env->scope->depth--;
+    CHECK_BB(check_fdef_effects(env, fdef));
     return ret;
   }
   return GW_OK;
 }
 
-ANN static bool effect_find(const MP_Vector *v, const Symbol sym) {
-  for(m_uint i = 0; i < v->len; i++) {
-    struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
-    if(eff->sym == sym) return true;
-  }
-  return false;
+ANN static m_bool check_ctor(const Env env, const Func func) {
+  if(!GET_FLAG(func, const) && nspc_lookup_value0(env->class_def->info->parent->nspc, insert_symbol("new")) && !GET_FLAG(func, const))
+    ERR_B(func->def->base->pos, "missing call to parent constructor");
+  return GW_OK;
 }
 
 ANN m_bool _check_func_def(const Env env, const Func_Def f) {
@@ -1838,19 +1862,6 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
   }
   vector_add(&env->scope->effects, 0);
   const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
-  MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
-  if (v) {
-    if (fdef->base->xid == insert_symbol("@dtor"))
-      ERR_B(fdef->base->pos, _("can't use effects in destructors"));
-    const Vector base = &fdef->base->effects;
-    if (!base->ptr) vector_init(base);
-    for (uint32_t i = 0; i < v->len; i++) {
-      struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
-      if(!effect_find(v, eff->sym))
-        vector_add(base, (m_uint)eff->sym);
-    }
-    free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
-  }
   vector_pop(&env->scope->effects);
   if (fbflag(fdef->base, fbflag_op)) operator_resume(&opi);
   nspc_pop_value(env->gwion->mp, env->curr);
@@ -1861,6 +1872,8 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
          !check_effect_overload(&fdef->base->effects, override->d.func_ref)))
       ERR_B(fdef->base->pos, _("too much effects in override."),
             s_name(fdef->base->xid))
+      if(is_new(f) && !tflag(env->class_def, tflag_struct))
+        CHECK_BB(check_ctor(env, func));
   }
   if (GET_FLAG(fdef->base, global)) env_pop(env, scope);
   if (func->value_ref->from->owner_class)