Exemple #1
0
ast_t* deferred_reify_method_def(deferred_reification_t* deferred, ast_t* ast,
  pass_opt_t* opt)
{
  switch(ast_id(ast))
  {
    case TK_FUN:
    case TK_BE:
    case TK_NEW:
      break;

    default:
      pony_assert(false);
  }

  // Do not duplicate the body and docstring.
  bool dup_child[9] = {true, true, true, true, true, true, false, false, true};
  ast_t* r_ast = ast_dup_partial(ast, dup_child, true, true, true);

  // Must replace `this` before typeparam reification.
  if(deferred->thistype != NULL)
    r_ast = viewpoint_replacethis(r_ast, deferred->thistype, false);

  if(deferred->type_typeparams != NULL)
    r_ast = reify(r_ast, deferred->type_typeparams, deferred->type_typeargs,
      opt, false);

  if(deferred->method_typeparams != NULL)
    r_ast = reify(r_ast, deferred->method_typeparams, deferred->method_typeargs,
      opt, false);

  return r_ast;
}
Exemple #2
0
void deferred_reify_add_method_typeparams(deferred_reification_t* deferred,
  ast_t* typeparams, ast_t* typeargs, pass_opt_t* opt)
{
  pony_assert((deferred->method_typeparams == NULL) &&
    (deferred->method_typeargs == NULL));

  pony_assert(((typeparams != NULL) && (typeargs != NULL)) ||
    ((typeparams == NULL) && (typeargs == NULL)));

  if(typeparams == NULL)
    return;

  ast_t* r_typeparams = ast_dup(typeparams);
  deferred->method_typeargs = ast_dup(typeargs);

  // Must replace `this` before typeparam reification.
  if(deferred->thistype != NULL)
    r_typeparams = viewpoint_replacethis(r_typeparams, deferred->thistype,
      false);

  if(deferred->type_typeparams != NULL)
    r_typeparams = reify(r_typeparams, deferred->type_typeparams,
      deferred->type_typeargs, opt, false);

  deferred->method_typeparams = r_typeparams;
}
Exemple #3
0
ast_t* viewpoint_reifythis(ast_t* type)
{
  ast_t* tuple = ast_from(type, TK_TUPLETYPE);

  ast_t* this_ref = ast_from(type, TK_REF);
  ast_append(tuple, viewpoint_replacethis(type, this_ref));
  ast_free_unattached(this_ref);

  ast_t* this_val = ast_from(type, TK_VAL);
  ast_append(tuple, viewpoint_replacethis(type, this_val));
  ast_free_unattached(this_val);

  ast_t* this_box = ast_from(type, TK_BOX);
  ast_append(tuple, viewpoint_replacethis(type, this_box));
  ast_free_unattached(this_box);

  return tuple;
}
Exemple #4
0
ast_t* deferred_reify(deferred_reification_t* deferred, ast_t* ast,
  pass_opt_t* opt)
{
  ast_t* r_ast = ast_dup(ast);

  // Must replace `this` before typeparam reification.
  if(deferred->thistype != NULL)
    r_ast = viewpoint_replacethis(r_ast, deferred->thistype, false);

  if(deferred->type_typeparams != NULL)
    r_ast = reify(r_ast, deferred->type_typeparams, deferred->type_typeargs,
      opt, false);

  if(deferred->method_typeparams != NULL)
    r_ast = reify(r_ast, deferred->method_typeparams, deferred->method_typeargs,
      opt, false);

  return r_ast;
}
Exemple #5
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;
}