]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add did you mean for traits
authorJérémie Astor <fennecdjay@gmail.com>
Mon, 9 Aug 2021 12:25:25 +0000 (14:25 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Mon, 9 Aug 2021 12:25:25 +0000 (14:25 +0200)
include/env/nspc.h
include/env/trait.h
src/parse/check_traits.c
src/parse/did_you_mean.c
src/parse/scan0.c

index dc590f697a647d3658de278820be6e8cbfe71bcf..920c3cb811da52f12589830930eb6f6fca01fec7 100644 (file)
@@ -70,6 +70,7 @@ describe_nspc_func(Value, value) describe_nspc_func(Type, type)
     /* howere there is no need for lookup_func0, push_func, pop_func */
     ANN void did_you_mean_nspc(const Nspc, const char *);
 ANN void did_you_mean_type(const Type, const char *);
+ANN void did_you_mean_trait(Nspc nspc, const char *name);
 
 #define DID_YOU_MEAN_LIMIT 128
 #define did_you_mean_nspc(a, b)                                                \
index a479a0205ebb07a30dfe09033dcda7a82db3dab5..7a1fea48e3cc49857d9af7aa6f9a132b57c21703 100644 (file)
@@ -4,6 +4,7 @@
 typedef struct Trait_ {
   struct Vector_ requested_values;
   struct Vector_ requested_funcs;
+  m_str          name;
   m_str          filename;
   loc_t          loc;
 } * Trait;
index 3b7b6c81b54a5cc313a34c33ce6f2d10b4621004..5f7b653bc3e10f843594215fe8ad576f8eb5e8dc 100644 (file)
@@ -124,8 +124,8 @@ ANN bool check_trait_requests(const Env env, const Type t, const ID_List list) {
     gwerr_secondary("duplicated trait", trait->filename, trait->loc);
     return false;
   }
-  const bool value_error = check_trait_variables(env, t, trait);
-  const bool funcs_error = check_trait_functions(env, t, trait);
+  const bool value_error = trait->requested_values.ptr  ? check_trait_variables(env, t, trait) : false;
+  const bool funcs_error = trait->requested_funcs.ptr ? check_trait_functions(env, t, trait) : false;
   if (!value_error && !funcs_error) return true;
   const Value request = (Value)vector_front(&trait->requested_values);
   gwerr_secondary("from trait", request->from->filename, trait->loc);
index dbce28b2eff6f2fee96b10327f5d858826ab01b8..4f8fd219371bc8b7991660d6d79b9cb0f77fd310 100644 (file)
@@ -29,9 +29,9 @@ static m_bool wagner_fisher(const char *s, const char *t) {
   return (i && j && d[m - 1][n - 1] < MAX_DISTANCE);
 }
 
-ANN static void ressembles(const Nspc nspc, const char *name,
+ANN static void ressembles(const Scope scope, const char *name,
                            bool *const done) {
-  struct scope_iter iter = {nspc->info->value, 0, 0};
+  struct scope_iter iter = { scope, 0, 0 };
   Value             value;
   while (scope_iter(&iter, &value) > 0) {
     if (wagner_fisher(name, value->name)) {
@@ -44,6 +44,22 @@ ANN static void ressembles(const Nspc nspc, const char *name,
   }
 }
 
+ANN static void trait_ressembles(const Scope scope, const char *name,
+                           bool *const done) {
+  struct scope_iter iter = { scope, 0, 0 };
+  Trait trait;
+  while (scope_iter(&iter, &trait) > 0) {
+    if (wagner_fisher(name, trait->name)) {
+      if (!*done) {
+        *done = true;
+        gw_err("{-/}did you mean{0}:\n");
+      }
+      if (trait->filename) // TODO: check why is that from check
+        gwerr_secondary(_("defined here"), trait->filename, trait->loc);
+    }
+  }
+}
+
 #define MAX_NAME_LEN 16
 #define CHECK_LEN(name)                                                        \
   if (strlen(name) > MAX_NAME_LEN) return;
@@ -52,7 +68,7 @@ ANN static void ressembles(const Nspc nspc, const char *name,
 ANN void did_you_mean_nspc(Nspc nspc, const char *name) {
   CHECK_LEN(name)
   bool done = false;
-  do ressembles(nspc, name, &done);
+  do ressembles(nspc->info->value, name, &done);
   while ((nspc = nspc->parent));
 }
 
@@ -60,6 +76,13 @@ ANN void did_you_mean_nspc(Nspc nspc, const char *name) {
 ANN void did_you_mean_type(Type type, const char *name) {
   CHECK_LEN(name)
   bool done = false;
-  do ressembles(type->nspc, name, &done);
+  do ressembles(type->nspc->info->value, name, &done);
   while ((type = type->info->parent) && type->nspc);
 }
+
+ANN void did_you_mean_trait(Nspc nspc, const char *name) {
+  CHECK_LEN(name)
+  bool done = false;
+  do trait_ressembles(nspc->info->trait, name, &done);
+  while ((nspc = nspc->parent));
+}
index 7c3adedacc9ced51cca3827d4c8b15be3a754a41..7cdfa37dbcd9461c6795d375f8d0a6fe64c245e1 100644 (file)
@@ -318,8 +318,12 @@ ANN static Type cdef_parent(const Env env, const Class_Def cdef) {
 
 ANN static m_bool find_traits(const Env env, ID_List traits, const loc_t pos) {
   do {
-    if (!nspc_lookup_trait1(env->curr, traits->xid))
-      ERR_B(pos, _("can't find trait"));
+    if (!nspc_lookup_trait1(env->curr, traits->xid)) {
+      gwerr_basic(_("can't find trait"), NULL, NULL, env->name, pos, 0);
+      did_you_mean_trait(env->curr, s_name(traits->xid));
+      env->context->error = true;
+      return GW_ERROR;
+    }
   } while ((traits = traits->next));
   return GW_OK;
 }
@@ -435,6 +439,7 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
 ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
   const Trait trait = new_trait(env->gwion->mp, pdef->pos);
   trait->loc        = pdef->pos;
+  trait->name       = s_name(pdef->xid);
   trait->filename   = env->name;
   nspc_add_trait(env->curr, pdef->xid, trait);
   Ast ast = pdef->body;