Lint

Description

Shows the warnings, notes and hints of the compiler for your sources, and fails on the ones you choose, so it can be used as a gate in a CI. Free Pascal has no standard linter, but with its messages on the compiler already reports uninitialized variables and results, unused units, parameters and variables, unreachable code, lossy conversions and more.

Example:

pasc lint

Building with warnings as errors (-Sew) does not work in a workspace: boss installs the dependencies as sources in modules, and they are compiled with the project, so the build stops in code that is not yours. pasc lint filters the messages by file after the compiler runs instead:

Linting apps/cmd
     OK cmd.lpr
Warning src/commands/Command.Count.pas
          apps/cmd/src/commands/Command.Count.pas:38:19 (5093) function result variable of a managed type does not seem to be initialized
     OK src/commands/Command.Greet.pas
     OK tests/Testcmd.lpr
     OK tests/TestCommandCount.pas
     OK tests/TestCommandGreet.pas
   Hint tests/TestOutput.pas
          25:58 (5024) Parameter "AColor" not used
Summary apps/cmd: 7 files, 5 OK, 1 warning, 1 hint, 1 failing

The exit code is 1 when a message fails or a project could not be built. Then the summary says why, like the first error of the compiler.

Rules

Besides the messages of the compiler, pasc lint has rules of its own, for what the compiler does not report. The sources of each member are parsed with fcl-passrc, the Pascal parser that comes with Free Pascal, also used by fpdoc and pas2js, so they need nothing else. Each rule has an id, and its findings go through the same configuration and output as the messages of the compiler, with the id in place of the number. The parser gives the line of each element but not its column, so a finding is at column 1.

id

kind

what it reports

PL001

note

A with statement, which hides where each identifier comes from.

PL002

warning

An empty except block, or an on handler without statements, which silently ignores the exception.

PL003

warning

A destructor that does not call inherited, so the parent does not free what it holds.

PL004

hint

A routine longer than 80 lines, its header included.

PL005

hint

A routine with more than 6 parameters.

PL006

hint

Statements nested more than 4 levels deep, in if, case, loops, try and with. Once per routine.

PL000

note

A source that the parser could not read, with the reason. The compiler still checks it.

The limits of PL004, PL005 and PL006 are in pasc.json:

"lint": {
  "rules": { "PL004": { "max": 60 }, "PL006": { "max": 3 } }
}

A finding can be turned off in the code with a comment on its line, or on the line above, with the ids of the rules or the numbers of the messages of the compiler:

except // pasc-lint: ignore PL002
  // nothing to do: the file may not exist yet
end;

Configuration

By default warnings fail, and notes and hints are shown. In the pasc.json of the workspace:

"lint": {
  "ignore": [5024],
  "fail": ["warning", 5091],
  "members": {
    "web": { "ignore": [5024, 5023] }
  }
}

The number of each message is in the output, between parentheses, and the complete list is in the Free Pascal documentation, or in the msg folder of the compiler sources.

Report

–report=<file> writes the totals as JSON, for a CI or a badge, without changing the output or the exit code:

pasc lint --report=lint.json

{
  "files" : 21,
  "ok" : 15,
  "errors" : 0,
  "warnings" : 1,
  "notes" : 0,
  "hints" : 8,
  "ignored" : 0,
  "failing" : 1,
  "notLinted" : 0
}

The lint badge of the pasc README is made from this report: its CI writes the kinds with messages, and a color, to the JSON that shields.io reads.

Next New Command


Generated by PasDoc 1.0.4.