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; }
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; }
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; }
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; }
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; }