Skip to content

cycle edge in include

Alexander Liberov edited this page Nov 13, 2026 · 1 revision

A cycle edge written in an include (cycle-edge-in-include)

A uses cycle runs through a uses entry or a declaration that is written in a {$I} include file. drag-lint cycles --fix edits uses clauses and declarations in .pas files and never edits an include, so it cannot untangle that cycle. This rule names the include and says what to move into the .pas.

Running it

drag-lint lint-all --db <project.sqlite> --rule cycle-edge-in-include
drag-lint lint-project --db <project.sqlite> --rule cycle-edge-in-include

It ships on, at severity hint, and runs on a project index. It uses the same strongly-connected groups that circular-uses reports, so the two rules always agree on which units cycle. An index built before the file facts (schema 24) yields nothing, and so does an index made with --no-preprocess.

Shape U: a uses entry in an include

unit LabIncA;
interface
uses
  {$I LabIncUses.inc}   // LabIncUses.inc holds:  LabIncB;

LabIncA uses LabIncB through the include, and LabIncB uses LabIncA back. The finding sits on the {$I} line of the host and names the host, the target, the include file (and the line inside it) and the cycle. Fix: write LabIncB in the uses clause of LabIncA.pas itself, or take the entry out of the include, then run drag-lint cycles --plan.

Shape D: a declaration in an include

unit IncDeclA;
interface
{$I IncDeclTypes.inc}   // declares TIncDeclARec

IncDeclB is in the same cycle and uses TIncDeclARec. cycles --fix would have to move the record into a leaf unit, and the record lives in a file it does not edit. The finding sits on the {$I} line that brings the include in and names the symbol, its kind, the include, and up to three units that use it. Only top-level declarations count: fields, members, parameters and locals are not listed. Fix: declare the type in the .pas of the host, or in a unit of its own.

An include shared by several units of the cycle gets one finding per host, and the message adds "also included by" the other hosts.

What stays silent

  • A uses entry or declaration written in the .pas.
  • An include-borne entry whose target is not in the same cycle as the host.
  • A declaration in an include that only units outside the cycle use.
  • An index with no cycle.

Reviewing it

A dl:ok cycle-edge-in-include@<hash> marker goes on the host's {$I} line, the line the finding is anchored at. Nothing in the include file changes.

Why drag-lint never edits an include

An include is shared text: one .inc can be pulled into several units, in different configurations, and an edit made from one host cannot be proven to leave the others compiling (ruling N-06 A5). cycles --plan still prints the step; this rule is the reminder that the step is yours to take by hand. See the cycles --fix plan.

Clone this wiki locally