/* 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) \
typedef struct Trait_ {
struct Vector_ requested_values;
struct Vector_ requested_funcs;
+ m_str name;
m_str filename;
loc_t loc;
} * Trait;
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);
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)) {
}
}
+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;
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));
}
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));
+}
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;
}
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;