/* * Generate the type hints for a single API overload. */ static void pyiOverload(sipSpec *pt, moduleDef *mod, overDef *od, int overloaded, int is_method, int sec, ifaceFileList *defined, int indent, int pep484, FILE *fp) { int need_self; if (overloaded) { prIndent(indent, fp); fprintf(fp, "@typing.overload\n"); } if (pep484 && is_method && isStatic(od)) { prIndent(indent, fp); fprintf(fp, "@staticmethod\n"); } prIndent(indent, fp); fprintf(fp, "%s%s", (pep484 ? "def " : ""), od->common->pyname->text); need_self = (is_method && !isStatic(od)); pyiPythonSignature(pt, mod, &od->pysig, need_self, sec, defined, od->kwargs, pep484, fp); if (pep484) fprintf(fp, ": ...\n"); }
/* * Generate an ctor type hint. */ static void pyiCtor(sipSpec *pt, moduleDef *mod, classDef *cd, ctorDef *ct, int overloaded, int sec, ifaceFileList *defined, int indent, FILE *fp) { int a, need_comma; if (overloaded) { prIndent(indent, fp); fprintf(fp, "@typing.overload\n"); } prIndent(indent, fp); if (cd == NULL) { fprintf(fp, "def __init__(self"); need_comma = TRUE; } else { prScopedPythonName(fp, cd->ecd, cd->pyname->text); fprintf(fp, "("); need_comma = FALSE; } for (a = 0; a < ct->pysig.nrArgs; ++a) need_comma = pyiArgument(pt, mod, &ct->pysig.args[a], a, FALSE, need_comma, sec, TRUE, TRUE, defined, ct->kwargs, (cd == NULL), fp); fprintf(fp, (cd == NULL) ? ") -> None: ...\n" : ")"); }
/* * Generate the APIs for all the enums in a scope. */ static void pyiEnums(sipSpec *pt, moduleDef *mod, ifaceFileDef *scope, ifaceFileList *defined, int indent, FILE *fp) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->module != mod) continue; if (ed->no_typehint) continue; if (scope != NULL) { if ((ed->ecd == NULL || ed->ecd->iff != scope) && (ed->emtd == NULL || ed->emtd->iff != scope)) continue; } else if (ed->ecd != NULL || ed->emtd != NULL) { continue; } separate(TRUE, indent, fp); if (ed->pyname != NULL) { prIndent(indent, fp); fprintf(fp, "class %s(int): ...\n", ed->pyname->text); } for (emd = ed->members; emd != NULL; emd = emd->next) { if (emd->no_typehint) continue; prIndent(indent, fp); fprintf(fp, "%s = ... # type: ", emd->pyname->text); if (ed->pyname != NULL) prEnumRef(ed, mod, defined, TRUE, fp); else fprintf(fp, "int"); fprintf(fp, "\n"); } } }
static void dumpBB(graph_t * g) { boxf bb; box b; bb = BB(g); b = GD_bb(g); prIndent(); fprintf(stderr, " LL (%f,%f) UR (%f,%f)\n", bb.LL.x, bb.LL.y, bb.UR.x, bb.UR.y); prIndent(); fprintf(stderr, " LL (%d,%d) UR (%d,%d)\n", b.LL.x, b.LL.y, b.UR.x, b.UR.y); }
/* * Generate the APIs for all the variables in a scope. */ static void pyiVars(sipSpec *pt, moduleDef *mod, classDef *scope, ifaceFileList *defined, int indent, FILE *fp) { int first = TRUE; varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->module != mod) continue; if (vd->ecd != scope) continue; if (vd->no_typehint) continue; first = separate(first, indent, fp); prIndent(indent, fp); fprintf(fp, "%s = ... # type: ", vd->pyname->text); pyiType(pt, mod, &vd->type, FALSE, FALSE, defined, TRUE, fp); fprintf(fp, "\n"); } }
/* * Generate handwritten type hint code. */ static void pyiTypeHintCode(codeBlockList *thc, int indent, FILE *fp) { while (thc != NULL) { int need_indent = TRUE; const char *cp; fprintf(fp, "\n"); for (cp = thc->block->frag; *cp != '\0'; ++cp) { if (need_indent) { need_indent = FALSE; prIndent(indent, fp); } fprintf(fp, "%c", *cp); if (*cp == '\n') need_indent = TRUE; } thc = thc->next; } }
/* dumpE: */ void dumpE(graph_t * g, int derived) { Agnode_t *n; Agedge_t *e; Agedge_t **ep; Agedge_t *el; int i; int deg; prIndent(); fprintf(stderr, "Graph %s : %d nodes %d edges\n", g->name, agnnodes(g), agnedges(g)); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { deg = 0; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { deg++; prIndent(); fprintf(stderr, " %s -- %s\n", e->tail->name, e->head->name); if (derived) { for (i = 0, ep = (Agedge_t **) ED_to_virt(e); i < ED_count(e); i++, ep++) { el = *ep; prIndent(); fprintf(stderr, " %s -- %s\n", el->tail->name, el->head->name); } } } if (deg == 0) { /* no out edges */ if (!agfstin(g, n)) /* no in edges */ fprintf(stderr, " %s\n", n->name); } } if (!derived) { bport_t *pp; if ((pp = PORTS(g))) { int sz = NPORTS(g); fprintf(stderr, " %d ports\n", sz); while (pp->e) { fprintf(stderr, " %s : %s -- %s\n", pp->n->name, pp->e->tail->name, pp->e->head->name); pp++; } } } }
/* * Generate the type hints for a mapped type. */ static void pyiMappedType(sipSpec *pt, moduleDef *mod, mappedTypeDef *mtd, ifaceFileList **defined, int indent, FILE *fp) { int first, no_body; memberDef *md; /* See if there is anything in the mapped type body. */ no_body = (mtd->members == NULL); if (no_body) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->no_typehint) continue; if (ed->emtd == mtd) { no_body = FALSE; break; } } } if (!no_body) { separate(TRUE, indent, fp); prIndent(indent, fp); fprintf(fp, "class %s(sip.wrapper):\n", mtd->pyname->text); ++indent; pyiEnums(pt, mod, mtd->iff, *defined, indent, fp); first = TRUE; for (md = mtd->members; md != NULL; md = md->next) { first = separate(first, indent, fp); pyiCallable(pt, mod, md, mtd->overs, TRUE, *defined, indent, fp); } } /* * Keep track of what has been defined so that forward references are no * longer required. */ appendToIfaceFileList(defined, mtd->iff); }
static void dumpSG(graph_t * g) { graph_t *subg; int i; if (GD_n_cluster(g) == 0) return; prIndent(); fprintf(stderr, " {\n"); for (i = 1; i <= GD_n_cluster(g); i++) { subg = (GD_clust(g))[i]; prIndent(); fprintf(stderr, " subgraph %s : %d nodes\n", subg->name, agnnodes(subg)); dumpBB(subg); incInd (); dumpSG(subg); decInd (); } prIndent(); fprintf(stderr, " }\n"); }
/* dump: */ void dump(graph_t * g, int level, int doBB) { node_t *n; boxf bb; double w, h; pointf pos; if (Verbose < level) return; prIndent(); fprintf(stderr, "Graph %s : %d nodes\n", g->name, agnnodes(g)); dumpBB(g); if (Verbose > level) { incInd(); dumpSG(g); decInd(); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { pos.x = ND_pos(n)[0]; pos.y = ND_pos(n)[1]; prIndent(); w = ND_width(n); h = ND_height(n); if (doBB) { bb.LL.x = pos.x - w / 2.0; bb.LL.y = pos.y - h / 2.0; bb.UR.x = bb.LL.x + w; bb.UR.y = bb.LL.y + h; fprintf(stderr, "%s: (%f,%f) ((%f,%f) , (%f,%f))\n", n->name, pos.x, pos.y, bb.LL.x, bb.LL.y, bb.UR.x, bb.UR.y); } else { fprintf(stderr, "%s: (%f,%f) (%f,%f) \n", n->name, pos.x, pos.y, w, h); } } } }
/* init_params: * Set parameters for expansion phase based on initial * layout parameters. If T0 is not set, we set it here * based on the size of the graph. In this case, we * return 1, so that fdp_tLayout can unset T0, to be * reset by a recursive call to fdp_tLayout. */ static int init_params (graph_t* g, xparams* xpms) { int ret = 0; if (T0 == -1.0) { int nnodes = agnnodes(g); T0 = T_Tfact*T_K*sqrt(nnodes)/5; #ifdef DEBUG if (Verbose) { prIndent(); fprintf (stderr, "tlayout %s : T0 %f\n", g->name, T0); } #endif ret = 1; } xpms->T0 = cool (T0, pass1); xpms->K = T_K; xpms->C = T_C; xpms->numIters = numIters - pass1; if (T_maxIter >= 0) { if (T_maxIter <= pass1) { loopcnt = T_maxIter; xpms->loopcnt = 0; } else if (T_maxIter <= numIters) { loopcnt = pass1; xpms->loopcnt = T_maxIter - pass1; } } else { loopcnt = pass1; xpms->loopcnt = xpms->numIters; } return ret; }
/* * Generate the type hints for a class. */ static void pyiClass(sipSpec *pt, moduleDef *mod, classDef *cd, ifaceFileList **defined, int indent, FILE *fp) { int first, no_body, nr_overloads; classDef *nested; ctorDef *ct; memberDef *md; separate(TRUE, indent, fp); prIndent(indent, fp); fprintf(fp, "class %s(", cd->pyname->text); if (cd->supers != NULL) { classList *cl; for (cl = cd->supers; cl != NULL; cl = cl->next) { if (cl != cd->supers) fprintf(fp, ", "); prClassRef(cl->cd, mod, *defined, TRUE, fp); } } else if (cd->supertype != NULL) { fprintf(fp, "%s", cd->supertype->text); } else if (cd->iff->type == namespace_iface) { fprintf(fp, "sip.simplewrapper"); } else { fprintf(fp, "sip.wrapper"); } /* See if there is anything in the class body. */ nr_overloads = 0; for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (ct->no_typehint) continue; if (!inDefaultAPI(pt, ct->api_range)) continue; ++nr_overloads; } no_body = (cd->typehintcode == NULL && nr_overloads == 0); if (no_body) { overDef *od; for (od = cd->overs; od != NULL; od = od->next) { if (isPrivate(od)) continue; if (od->no_typehint) continue; if (inDefaultAPI(pt, od->api_range)) { no_body = FALSE; break; } } } if (no_body) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->no_typehint) continue; if (ed->ecd == cd) { no_body = FALSE; break; } } } if (no_body) { for (nested = pt->classes; nested != NULL; nested = nested->next) { if (nested->no_typehint) continue; if (nested->ecd == cd) { no_body = FALSE; break; } } } if (no_body) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->no_typehint) continue; if (vd->ecd == cd) { no_body = FALSE; break; } } } fprintf(fp, "):%s\n", (no_body ? " ..." : "")); ++indent; pyiTypeHintCode(cd->typehintcode, indent, fp); pyiEnums(pt, mod, cd->iff, *defined, indent, fp); /* Handle any nested classes. */ for (nested = pt->classes; nested != NULL; nested = nested->next) { classDef *impl = getClassImplementation(pt, nested); if (impl != NULL && impl->ecd == cd && !impl->no_typehint) pyiClass(pt, mod, impl, defined, indent, fp); } pyiVars(pt, mod, cd, *defined, indent, fp); first = TRUE; for (ct = cd->ctors; ct != NULL; ct = ct->next) { int implicit_overloads, overloaded; if (isPrivateCtor(ct)) continue; if (ct->no_typehint) continue; if (!inDefaultAPI(pt, ct->api_range)) continue; implicit_overloads = hasImplicitOverloads(&ct->pysig); overloaded = (implicit_overloads || nr_overloads > 1); first = separate(first, indent, fp); pyiCtor(pt, mod, NULL, ct, overloaded, FALSE, *defined, indent, fp); if (implicit_overloads) pyiCtor(pt, mod, NULL, ct, overloaded, TRUE, *defined, indent, fp); } first = TRUE; for (md = cd->members; md != NULL; md = md->next) { /* * Ignore slots which can return Py_NotImplemented as code may be * correctly handled elsewhere. We also have to include the sequence * slots because they can't be distinguished from the number slots of * the same name. */ if (isNumberSlot(md) || isInplaceNumberSlot(md) || isRichCompareSlot(md) || md->slot == concat_slot || md->slot == iconcat_slot || md->slot == repeat_slot || md->slot == irepeat_slot) continue; first = separate(first, indent, fp); pyiCallable(pt, mod, md, cd->overs, TRUE, *defined, indent, fp); } /* * Keep track of what has been defined so that forward references are no * longer required. */ appendToIfaceFileList(defined, cd->iff); }