Exemplo n.º 1
0
static bool names_resolvealias(pass_opt_t* opt, ast_t* def, ast_t** type)
{
  ast_state_t state = (ast_state_t)((uint64_t)ast_data(def));

  switch(state)
  {
    case AST_STATE_INITIAL:
      ast_setdata(def, (void*)AST_STATE_INPROGRESS);
      break;

    case AST_STATE_INPROGRESS:
      ast_error(def, "type aliases can't be recursive");
      ast_setdata(def, (void*)AST_STATE_ERROR);
      return false;

    case AST_STATE_DONE:
      return true;

    case AST_STATE_ERROR:
      return false;

    default:
      assert(0);
      return false;
  }

  if(ast_visit_scope(type, NULL, pass_names, opt,
    PASS_NAME_RESOLUTION) != AST_OK)
    return false;

  ast_setdata(def, (void*)AST_STATE_DONE);
  return true;
}
Exemplo n.º 2
0
static ast_t* lookup_nominal(pass_opt_t* opt, ast_t* from, ast_t* orig,
                             ast_t* type, const char* name, bool errors)
{
    assert(ast_id(type) == TK_NOMINAL);
    typecheck_t* t = &opt->check;

    ast_t* def = (ast_t*)ast_data(type);
    AST_GET_CHILDREN(def, type_id, typeparams);
    const char* type_name = ast_name(type_id);

    if((type_name[0] == '_') && (from != NULL) && (opt != NULL))
    {
        if(ast_nearest(def, TK_PACKAGE) != t->frame->package)
        {
            if(errors)
            {
                ast_error(from,
                          "can't lookup fields or methods on private types from other packages"
                         );
            }

            return NULL;
        }
    }

    ast_t* find = ast_get(def, name, NULL);

    if(find != NULL)
    {
        switch(ast_id(find))
        {
        case TK_FVAR:
        case TK_FLET:
        case TK_EMBED:
            break;

        case TK_NEW:
        case TK_BE:
        case TK_FUN:
        {
            // Typecheck default args immediately.
            if(opt != NULL)
            {
                AST_GET_CHILDREN(find, cap, id, typeparams, params);
                ast_t* param = ast_child(params);

                while(param != NULL)
                {
                    AST_GET_CHILDREN(param, name, type, def_arg);

                    if((ast_id(def_arg) != TK_NONE) && (ast_type(def_arg) == NULL))
                    {
                        ast_settype(def_arg, ast_from(def_arg, TK_INFERTYPE));

                        if(ast_visit_scope(&def_arg, NULL, pass_expr, opt,
                                           PASS_EXPR) != AST_OK)
                            return false;

                        ast_visit_scope(&def_arg, NULL, pass_nodebug, opt, PASS_ALL);
                    }

                    param = ast_sibling(param);
                }
            }
            break;
        }

        default:
            find = NULL;
        }
    }

    if(find == NULL)
    {
        if(errors)
            ast_error(from, "couldn't find '%s' in '%s'", name, type_name);

        return NULL;
    }

    if((name[0] == '_') && (from != NULL) && (opt != NULL))
    {
        switch(ast_id(find))
        {
        case TK_FVAR:
        case TK_FLET:
        case TK_EMBED:
            if(t->frame->type != def)
            {
                if(errors)
                {
                    ast_error(from,
                              "can't lookup private fields from outside the type");
                }

                return NULL;
            }
            break;

        case TK_NEW:
        case TK_BE:
        case TK_FUN:
        {
            if(ast_nearest(def, TK_PACKAGE) != t->frame->package)
            {
                if(errors)
                {
                    ast_error(from,
                              "can't lookup private methods from outside the package");
                }

                return NULL;
            }
            break;
        }

        default:
            assert(0);
            return NULL;
        }

        if(!strcmp(name, "_final"))
        {
            switch(ast_id(find))
            {
            case TK_NEW:
            case TK_BE:
            case TK_FUN:
                if(errors)
                    ast_error(from, "can't lookup a _final function");

                return NULL;

            default:
            {}
            }
        }
    }

    ast_t* typeargs = ast_childidx(type, 2);
    ast_t* r_find = viewpoint_replacethis(find, orig);
    ast_t* rr_find = reify(r_find, typeparams, typeargs);
    ast_free_unattached(r_find);
    return rr_find;
}