Composer.Lint.Diagnostic (composer v0.2.0)

Copy Markdown View Source

One problem found by Composer.Lint: what is wrong, how bad it is, and where.

The shape follows an LSP Diagnostic, so an editor integration only has to translate it:

  • severity - :error or :warning
  • code - the reason's tag (:typo, :missing_step, :cycle, :unused_alias, ...). Codes are public and stable; they are listed in the lint guide.
  • file - an absolute path, or nil when nothing can be located
  • line, column - where the problem starts; end_line, end_column - where it ends (exclusive). nil when only the file is known.
  • message - the full text of Composer.Error.message/1
  • reason - the raw reason tuple
  • suggestions - replacement references, from the typo, missing_step and missing_recipe reasons
  • related - other places involved, as %{file, range, message} (the other origin of a conflicting_install, each hop of a cycle, the first key of a duplicate_recipe, ...)

Positions

Lines and columns are 1-based. Columns count characters as Elixir's tokenizer does (grapheme clusters), not bytes or UTF-16 code units. When column is set, end_line and end_column are set too. A range is {{line, column}, {end_line, end_column}}.

Summary

Functions

The diagnostic code of a reason: its tag.

True for an error.

Places a diagnostic: in file, over range (or at no particular position when range is nil), with related locations.

An unlocated diagnostic for reason.

The diagnostic's range, or nil.

The suggested replacements carried by a reason (typo, missing_step, missing_recipe, also behind a cookbook alias).

The diagnostic as JSON-ready data. reason is left out: tuples do not encode.

Types

position()

@type position() :: {pos_integer(), pos_integer()}

range()

@type range() :: {position(), position()}

related()

@type related() :: %{file: Path.t() | nil, range: range() | nil, message: String.t()}

t()

@type t() :: %Composer.Lint.Diagnostic{
  code: atom(),
  column: pos_integer() | nil,
  end_column: pos_integer() | nil,
  end_line: pos_integer() | nil,
  file: Path.t() | nil,
  line: pos_integer() | nil,
  message: String.t(),
  reason: term(),
  related: [related()],
  severity: :error | :warning,
  suggestions: [String.t()]
}

Functions

code(reason)

@spec code(term()) :: atom()

The diagnostic code of a reason: its tag.

error?(diagnostic)

@spec error?(t()) :: boolean()

True for an error.

locate(diagnostic, file, range, related \\ [])

@spec locate(t(), Path.t() | nil, range() | nil, [related()]) :: t()

Places a diagnostic: in file, over range (or at no particular position when range is nil), with related locations.

new(severity, reason)

@spec new(:error | :warning, term()) :: t()

An unlocated diagnostic for reason.

range(d)

@spec range(t()) :: range() | nil

The diagnostic's range, or nil.

suggestions(arg1)

@spec suggestions(term()) :: [String.t()]

The suggested replacements carried by a reason (typo, missing_step, missing_recipe, also behind a cookbook alias).

to_map(d)

@spec to_map(t()) :: map()

The diagnostic as JSON-ready data. reason is left out: tuples do not encode.