import intsets, ast, idents, algorithm, renderer, strutils, msgs, modulegraphs, syntaxes, options, modulepaths, lineinfos type DepN = ref object pnode: PNode id, idx, lowLink: int onStack: bool kids: seq[DepN] hAQ, hIS, hB, hCmd: int when defined(debugReorder): expls: seq[string] DepG = seq[DepN] when defined(debugReorder): var idNames = newTable[int, string]() proc newDepN(id: int, pnode: PNode): DepN = new(result) result.id = id result.pnode = pnode result.idx = -1 result.lowLink = -1 result.onStack = false result.kids = @[] result.hAQ = -1 result.hIS = -1 result.hB = -1 result.hCmd = -1 when defined(debugReorder): result.expls = @[] proc accQuoted(cache: IdentCache; n: PNode): PIdent = var id = "" for i in 0..= 3: decl(a[0]) for i in 1.. 1: for b in a: var s = newNode(a.kind) s.info = b.info s.add b result.add s else: result.add a proc haveSameKind(dns: seq[DepN]): bool = # Check if all the nodes in a strongly connected # component have the same kind result = true let kind = dns[0].pnode.kind for dn in dns: if dn.pnode.kind != kind: return false proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) = # Merges typeSections and ConstSections when they form # a strong component (ex: circular type definition) for c in comps: assert c.len > 0 if c.len == 1: res.add c[0].pnode else: let fstn = c[0].pnode let kind = fstn.kind # always return to the original order when we got circular dependencies let cs = c.sortedByIt(it.id) if kind in {nkTypeSection, nkConstSection} and haveSameKind(cs): # Circular dependency between type or const sections, we just # need to merge them var sn = newNode(kind) for dn in cs: sn.add dn.pnode[0] res.add sn else: # Problematic circular dependency, we arrange the nodes into # their original relative order and make sure to re-merge # consecutive type and const sections var wmsg = "Circular dependency detected. `codeReordering` pragma may not be able to" & " reorder some nodes properly" when defined(debugReorder): wmsg &= ":\n" for i in 0..