agentleFS
ericwood8ericwood8/skills/delphi-code-smells/SKILL.md

delphi-code-smells

Skill1 starsChanged 13 days agoMITView on GitHub

Use when reviewing existing Delphi / Object Pascal code for defects, hunting a memory leak or an access violation, or hardening new code against the classic mistakes. Covers compiler warnings and hints that indicate a real bug, warnings-as-errors, leak detection and how to make a leak fail a build, third-party static analysis, and a catalogue of smells each with a way to find it. Triggers on "code smell", "code review", "review this unit", "refactor this unit", "memory leak", "leak", "leaking", "double free", "access violation", "AV", "static analysis", "lint", "compiler warning", "W1035", "$WARN", "warnings as errors", "FastMM", "ReportMemoryLeaksOnShutdown", "audit this code".

2 other projects use a version of this, 2 of them edited.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Every warning code, directive and API below was produced by dcc32.exe 37.0 on this machine or copied from the shipped RTL/DUnitX source, …

    line 11
  2. Very specific:

    Run it with ReportMemoryLeaksOnShutdown := True: If there is a test suite, run that.

    line 35
  3. Very specific:

    If a compiler warning already covers a finding, cite the code (W1035) — it turns your opinion into something the user can put in their …

    line 107
  4. Distinctive:

    Never report a smell you cannot say how to detect.

    line 109

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Delphi code smells — make the machine find them first

A review pass that starts with an opinion is worth little. A review pass that starts with the compiler and a leak report is worth a lot, because it is objective and free. Do that half first, every time.

Every warning code, directive and API below was produced by dcc32.exe 37.0 on this machine or copied from the shipped RTL/DUnitX source, not recalled. Where something could not be verified it says so.


What this skill owns, and what it does not

QuestionWhere it is answered
Why does this leak? How does ownership work? Free, try/finally, interfaces, refcounting, TObjectList<T>, TComponent, managed recordsdelphi, reference/memory.md — not restated here
What is the right try/except shape? What must I never catch?delphi, reference/exceptions.md
Synchronize vs Queue, locks, FreeOnTerminatedelphi, reference/concurrency.md
How do I find the leak? How do I prove it? How do I stop it coming back?here

This skill is diagnosis. When a smell needs semantics to explain, it links; it does not re-teach.


Order of attack — an unfamiliar unit

Work down this list. Stop reporting when you run out of items that cost the user something.

  1. Compile it with warnings and hints on and read every line of output. Free, objective, and the single highest-yield step. reference/static-analysis.md.
  2. Run it with ReportMemoryLeaksOnShutdown := True. If there is a test suite, run that. reference/leaks.md.
  3. Ownership by hand — every Create in the unit: who frees it, on which paths, including the raising one. This is where the compiler cannot help you.
  4. Exception handling — every except without an on, every empty handler, every try/except that should have been try/finally.
  5. Concurrency — anything reachable from a TThread.Execute or a TTask.Run body.
  6. Everything else. Naming, with, long methods, magic numbers.

A leak the compiler cannot see outranks a naming convention, always. If the review output is a wall of style nits and no lifetime finding, the review was not done. Report defects in the order above, and say for each one what it costs at runtime — a leak, an AV, a silently wrong result. "This is ugly" is not a finding.


The five-minute pass

# 1. what the compiler already knows (see reference/static-analysis.md for the codes)
dcc32.exe -H -W MyProject.dpr

# 2. the greps that pay for themselves, in rough order of yield
rg -n -U 'try\b[^;]*?\n\s*\w+\s*:=\s*T\w+\.Create'   # constructor INSIDE the try  -> AV in the finally
rg -n -P '(?s)except\s*(//[^\n]*\n\s*)*end'          # swallowed exception
rg -n '\bwith\b\s+\w+.*\bdo\b'                       # with
rg -n 'FreeAndNil\s*\(\s*[lL]'                       # FreeAndNil on a local
rg -n 'FreeOnTerminate'                              # thread lifetime
rg -n '\w+\s*:=\s*\w+\s*\+\s*'                       # candidate string concat in a loop

Then read reference/smells.md for what each hit means and how to fix it.


Reference files

FileRead it when
reference/static-analysis.mdCompiler warnings and hints (verified codes), $WARN, turning a warning into an error, the build switches, and an honest note on Pascal Analyzer / SonarDelphi / FixInsight / madExcept / Error Insight
reference/leaks.mdFinding, reproducing and fencing a leak: the shipped memory manager, ReportMemoryLeaksOnShutdown, reading the report, RegisterExpectedMemoryLeak, and DUnitX per-test leak detection — the item that makes a leak fail a build
reference/smells.mdThe catalogue. Each entry: the bad code, what it costs at runtime, the fix, and how to detect it

The defects worth finding, ranked

Detail and detection for each in reference/smells.md.

#DefectCosts you
1Constructor inside the tryDestroy called on uninitialised memory — AV
2Object created and never freed on some pathLeak
3Create in a loop, Free after itLeak, once per iteration
4Object held as both a class reference and an interfaceDouble free, or a dangling pointer
5Two objects holding interfaces to each otherLeak the shutdown report shows as a matched pair
6except endThe diagnosis is deleted; the program carries on wrong
7try/except where try/finally was meantResource is released only when something raised
8Result not assigned on every pathCaller reads garbage. W1035
9Event handler / observer never unsubscribedAV when the publisher fires into a freed subscriber
10A function that returns an object nobody knows they ownLeak, or a double free
11Worker thread touching the VCLAV, once a week, on the customer's machine
12A thread outliving the object it capturedAV at shutdown
13Method silently hiding an ancestor's virtualWrong method runs. W1010
14withA field added later hijacks a name; silent, compiles
15Magic literal used as a status codeWrong branch after any refactor

Reporting a review

  • One line per finding: location, what goes wrong at runtime, the fix. Not an essay.
  • Lead with anything that leaks, dangles or returns a wrong value. Style last, or not at all.
  • If a compiler warning already covers a finding, cite the code (W1035) — it turns your opinion into something the user can put in their build and never hear from you again about.
  • Never report a smell you cannot say how to detect. If you cannot name a warning, a tool or a grep for it, it is a preference, and the user did not ask for your preferences.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.