PyObject * packagelist_to_pylist(HyPackageList plist, PyObject *sack) { HyPackage cpkg; PyObject *list; PyObject *retval; list = PyList_New(0); if (list == NULL) return NULL; retval = list; int i; FOR_PACKAGELIST(cpkg, plist, i) { PyObject *package = new_package(sack, package_id(cpkg)); if (package == NULL) { retval = NULL; break; } int rc = PyList_Append(list, package); Py_DECREF(package); if (rc == -1) { retval = NULL; break; } }
END_TEST START_TEST(test_get_clone) { HySack sack = test_globals.sack; int max = sack_last_solvable(sack); fail_unless(hy_packageset_count(pset) == 3); HyPackage pkg0 = hy_packageset_get_clone(pset, 0); HyPackage pkg9 = hy_packageset_get_clone(pset, 1); HyPackage pkg_max = hy_packageset_get_clone(pset, 2); fail_unless(package_id(pkg0) == 0); fail_unless(package_id(pkg9) == 9); fail_unless(package_id(pkg_max) == max); fail_unless(hy_packageset_get_clone(pset, 3) == NULL); hy_package_free(pkg0); hy_package_free(pkg9); hy_package_free(pkg_max); HyPackage pkg8 = package_create(sack, 8); HyPackage pkg11 = package_create(sack, 11); hy_packageset_add(pset, pkg8); hy_packageset_add(pset, pkg11); pkg8 = hy_packageset_get_clone(pset, 1); pkg9 = hy_packageset_get_clone(pset, 2); pkg11 = hy_packageset_get_clone(pset, 3); fail_unless(package_id(pkg8) == 8); fail_unless(package_id(pkg9) == 9); fail_unless(package_id(pkg11) == 11); hy_package_free(pkg8); hy_package_free(pkg9); hy_package_free(pkg11); }
int pkgmark_isset(const struct pkgmark_set *pmark, const struct pkg *pkg, uint32_t flag) { struct pkg_mark *pkg_mark; char idbuf[512]; const char *id; id = package_id(idbuf, sizeof(idbuf), pmark, pkg); n_assert(id); if ((pkg_mark = n_hash_get(pmark->ht, id))) return pkg_mark->flags & flag; return 0; }
/* make Sack think k-1-1 is the running kernel */ static Id mock_running_kernel(HySack sack) { HyQuery q = hy_query_create(sack); hy_query_filter(q, HY_PKG_NAME, HY_EQ, "k"); hy_query_filter(q, HY_PKG_EVR, HY_EQ, "1-1"); HyPackageList plist = hy_query_run(q); fail_unless(hy_packagelist_count(plist) == 1); HyPackage pkg = hy_packagelist_get_clone(plist, 0); hy_query_free(q); hy_packagelist_free(plist); Id id = package_id(pkg); hy_package_free(pkg); return id; }
HyPackage package_clone(HyPackage pkg) { return package_create(package_sack(pkg), package_id(pkg)); }
long package_hash(_PackageObject *self) { return package_id(self->package); }
// Sugar for partial application, which we convert to a lambda. static bool partial_application(pass_opt_t* opt, ast_t** astp) { /* Example that we refer to throughout this function. * ```pony * class C * fun f[T](a: A, b: B = b_default): R * * let recv: T = ... * recv~f[T2](foo) * ``` * * Partial call is converted to: * ```pony * {(b: B = b_default)($0 = recv, a = foo): R => $0.f[T2](a, consume b) } * ``` */ ast_t* ast = *astp; typecheck_t* t = &opt->check; if(!method_application(opt, ast, true)) return false; AST_GET_CHILDREN(ast, positional, namedargs, question, lhs); // LHS must be an application, possibly wrapped in another application // if the method had type parameters for qualification. pony_assert(ast_id(lhs) == TK_FUNAPP || ast_id(lhs) == TK_BEAPP || ast_id(lhs) == TK_NEWAPP); AST_GET_CHILDREN(lhs, receiver, method); ast_t* type_args = NULL; if(ast_id(receiver) == ast_id(lhs)) { type_args = method; AST_GET_CHILDREN_NO_DECL(receiver, receiver, method); } // Look up the original method definition for this method call. ast_t* method_def = lookup(opt, lhs, ast_type(receiver), ast_name(method)); pony_assert(ast_id(method_def) == TK_FUN || ast_id(method_def) == TK_BE || ast_id(method_def) == TK_NEW); // The TK_FUNTYPE of the LHS. ast_t* type = ast_type(lhs); pony_assert(ast_id(type) == TK_FUNTYPE); if(is_typecheck_error(type)) return false; AST_GET_CHILDREN(type, cap, type_params, target_params, result); bool bare = ast_id(cap) == TK_AT; token_id apply_cap = TK_AT; if(!bare) apply_cap = partial_application_cap(opt, type, receiver, positional); token_id can_error = ast_id(ast_childidx(method_def, 5)); const char* recv_name = package_hygienic_id(t); // Build lambda expression. ast_t* call_receiver = NULL; if(bare) { ast_t* arg = ast_child(positional); while(arg != NULL) { if(ast_id(arg) != TK_NONE) { ast_error(opt->check.errors, arg, "the partial application of a bare " "method cannot take arguments"); return false; } arg = ast_sibling(arg); } ast_t* receiver_type = ast_type(receiver); if(is_bare(receiver_type)) { // Partial application on a bare object, simply return the object itself. ast_replace(astp, receiver); return true; } AST_GET_CHILDREN(receiver_type, recv_type_package, recv_type_name); const char* recv_package_str = ast_name(recv_type_package); const char* recv_name_str = ast_name(recv_type_name); ast_t* module = ast_nearest(ast, TK_MODULE); ast_t* package = ast_parent(module); ast_t* pkg_id = package_id(package); const char* pkg_str = ast_name(pkg_id); const char* pkg_alias = NULL; if(recv_package_str != pkg_str) pkg_alias = package_alias_from_id(module, recv_package_str); ast_free_unattached(pkg_id); if(pkg_alias != NULL) { // `package.Type.f` BUILD_NO_DECL(call_receiver, ast, NODE(TK_DOT, NODE(TK_DOT, NODE(TK_REFERENCE, ID(pkg_alias)) ID(recv_name_str)) TREE(method))); } else { // `Type.f` BUILD_NO_DECL(call_receiver, ast, NODE(TK_DOT, NODE(TK_REFERENCE, ID(recv_name_str)) TREE(method))); } } else { // `$0.f` BUILD_NO_DECL(call_receiver, ast, NODE(TK_DOT, NODE(TK_REFERENCE, ID(recv_name)) TREE(method))); } ast_t* captures = NULL; if(bare) { captures = ast_from(receiver, TK_NONE); } else { // Build captures. We always have at least one capture, for receiver. // Capture: `$0 = recv` BUILD_NO_DECL(captures, receiver, NODE(TK_LAMBDACAPTURES, NODE(TK_LAMBDACAPTURE, ID(recv_name) NONE // Infer type. TREE(receiver)))); } // Process arguments. ast_t* target_param = ast_child(target_params); ast_t* lambda_params = ast_from(target_params, TK_NONE); ast_t* lambda_call_args = ast_from(positional, TK_NONE); ast_t* given_arg = ast_child(positional); while(given_arg != NULL) { pony_assert(target_param != NULL); const char* target_p_name = ast_name(ast_child(target_param)); if(ast_id(given_arg) == TK_NONE) { // This argument is not supplied already, must be a lambda parameter. // Like `b` in example above. // Build a new a new TK_PARAM node rather than copying the target one, // since the target has already been processed to expr pass, and we need // a clean one. AST_GET_CHILDREN(target_param, p_id, p_type, p_default); // Parameter: `b: B = b_default` BUILD(lambda_param, target_param, NODE(TK_PARAM, TREE(p_id) TREE(sanitise_type(p_type)) TREE(p_default))); ast_append(lambda_params, lambda_param); ast_setid(lambda_params, TK_PARAMS); // Argument: `consume b` BUILD(target_arg, lambda_param, NODE(TK_SEQ, NODE(TK_CONSUME, NONE NODE(TK_REFERENCE, ID(target_p_name))))); ast_append(lambda_call_args, target_arg); ast_setid(lambda_call_args, TK_POSITIONALARGS); } else { // This argument is supplied to the partial, capture it. // Like `a` in example above. // Capture: `a = foo` BUILD(capture, given_arg, NODE(TK_LAMBDACAPTURE, ID(target_p_name) NONE TREE(given_arg))); ast_append(captures, capture); // Argument: `a` BUILD(target_arg, given_arg, NODE(TK_SEQ, NODE(TK_REFERENCE, ID(target_p_name)))); ast_append(lambda_call_args, target_arg); ast_setid(lambda_call_args, TK_POSITIONALARGS); } given_arg = ast_sibling(given_arg); target_param = ast_sibling(target_param); } pony_assert(target_param == NULL); if(type_args != NULL) { // The partial call has type args, add them to the actual call in apply(). // `$0.f[T2]` BUILD(qualified, type_args, NODE(TK_QUALIFY, TREE(call_receiver) TREE(type_args))); call_receiver = qualified; } REPLACE(astp, NODE((bare ? TK_BARELAMBDA : TK_LAMBDA), NODE(apply_cap) NONE // Lambda function name. NONE // Lambda type params. TREE(lambda_params) TREE(captures) TREE(sanitise_type(result)) NODE(can_error) NODE(TK_SEQ, NODE(TK_CALL, TREE(lambda_call_args) NONE // Named args. NODE(can_error) TREE(call_receiver))) NONE)); // Lambda reference capability. // Need to preserve various lambda children. ast_setflag(ast_childidx(*astp, 2), AST_FLAG_PRESERVE); // Type params. ast_setflag(ast_childidx(*astp, 3), AST_FLAG_PRESERVE); // Parameters. ast_setflag(ast_childidx(*astp, 5), AST_FLAG_PRESERVE); // Return type. ast_setflag(ast_childidx(*astp, 7), AST_FLAG_PRESERVE); // Body. // Catch up to this pass. return ast_passes_subtree(astp, opt, PASS_EXPR); }