Repository navigation
target compiler
--target-compiler <ver|auto> tells lint, lint-all and rules the oldest Delphi compiler the code must still compile on. Modernize advice that needs a newer compiler is then not reported, so a project that has to build on Delphi 12 (or 10.4, or XE7) no longer hears "write X is not T" or "use an if expression". The default is 37 (Delphi 13): without the switch nothing changes.
drag-lint lint <file.pas> --target-compiler 12 (Delphi 12 = CompilerVersion 36)
drag-lint lint-all --db <db> --target-compiler 10.4
drag-lint lint-all --db <db> --project <x.dproj> --target-compiler auto (from the .dproj ProjectVersion)
drag-lint rules --json --target-compiler 36 (target_active per rule at that target)
Accepted tokens: product versions 13, 12, 12.2, 11, 10.4, 10.3, 10.2, 10.1, 10, XE8 .. XE2, XE, 2010, 2009, 2007, 2005, 7, 6, 5 .. 1 (an optional Delphi prefix, D5 .. D1 and the code names Florence, Athens, Alexandria, Sydney, Rio, Tokyo, Berlin, Seattle work too), a conditional symbol VER80 .. VER370 (VER130 = Delphi 5), or a CompilerVersion 14 .. 37. A bare 13 is Delphi 13, never CompilerVersion 13. An unknown token exits 2 and lists the accepted set.
Delphi 5 has no CompilerVersion constant (Delphi 6 = 14.0 introduced it); it defines VER130. drag-lint numbers VER80 .. VER130 as 8 .. 13, so D5 is target 13: --target-compiler 5. The preprocessor then describes that compiler's own symbols: VER130, WIN32, CPU386, and not CONDITIONALEXPRESSIONS, UNICODE, MSWINDOWS or WIN64, whatever --platform says. That set comes from the Delphi 5 documentation and has not been measured against a D5 compiler. Nothing here turns code into Delphi 5 code: D5 is upconvert only.
Nothing is detected from the machine: on a D5 VM with no RAD Studio a run with no token and no config still describes 37. Pass the token or set target_compiler.
auto reads the <ProjectVersion> of the .dproj named by --project (20.4 -> 37, 20.1-20.3 -> 36, 19.3-19.5 -> 35, 19.0-19.2 -> 34, 18.5-18.8 -> 33, 18.2-18.4 -> 32, 18.1 -> 31). A value outside that table exits 2. On a .dpr / .dpk it reads the .dproj beside it; with none, nothing names the compiler, so it assumes Delphi 5 (13) and says so on stderr. auto with no project at all exits 2. ProjectVersion says which IDE last saved the project, not which compilers must accept it -- name the version when they differ.
{ "target_compiler": "13", "profiles": { "legacy": { "target_compiler": "12" } } }"target_compiler" in drag-lint-lint.json takes the same tokens. A profile overrides it (--profile legacy), and --target-compiler on the command line wins over both. Fix it / Fix all in the IDE run the engine with the project's config, so a project that sets the key is linted and fixed for its target from the IDE too.
Order of precedence: command line, then the config (after --profile), then the project context file's targetCompiler, then 37.
drag-lint index --project <x.dproj> --db <db> (VER<N>0 from the .dproj ProjectVersion)
drag-lint index --project <x.dproj> --db <db> --target-compiler 10.3 (VER330, whatever the .dproj says)
drag-lint index --all [--jobs N] (each section from ITS OWN .dproj)
The indexer's preprocessor defines VER<N>0, CompilerVersion and RTLVersion for the Delphi the code is parsed for, so {$IFDEF VER330} / {$IF CompilerVersion >= 35} branches parse as that compiler would take them. Precedence: --target-compiler, then the <ProjectVersion> of the --project .dproj, then the installed RAD Studio. index --all applies this per section (a .dpr root uses its sibling .dproj; a section without one gets the installed Delphi, never the previous section's), in --jobs N children too. A non-37 target adds a cv=<N> limb to the indexer fingerprint, so changing it re-parses that index. From outside PRs #8 and #11 (Jonathas Paiva).
| rule | what its advice needs | gated below |
|---|---|---|
is-not-operator |
X is not T |
37 (Delphi 13) |
ifthen-to-if-expression |
X := if C then A else B |
37 |
nonminimal-bool, the not (A in S) form only |
A not in S |
37 |
unreadable-literal |
digit separators 1_000
|
35 (Delphi 11) |
pos-for-contains, the Contains forms |
TStringHelper.Contains |
24 (XE3) |
manual-inrange |
System.Math.InRange |
14 (Delphi 6) |
The inline-var fixes of swap-without-temp, field-by-name-in-loop and index-loop-to-for-in need 33 (10.3): below that the finding is still reported, the edit is skipped, and stderr says N fix(es) skipped (target-compiler).
A non-default target prints one line on stderr: target-compiler: 36 (Delphi 12) -- N modernize rule(s) gated, M compat rule(s) on.
Every row carries needs_compiler (0 = any compiler), compat_since (0 = not a compat rule) and target_active (does the rule run by default at this target; equal to default_enabled at 37). The root carries target_compiler.
A sidecar .json gates its rule with "needs_compiler": N; the same key on one fix entry gates only the matches that entry would fix. A rule of category compat carries "compat_since": N, ships "enabled": false, and is switched on for a run whose target is older than N. See rules/README.md. The downgrade rules themselves are a separate entry: Downgrade fixes.