Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .exp/design-workflow-5-lint-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,38 @@ sequenceDiagram
Driver->>Compiler: run compilation with registered lints
Store->>Compiler: execute lint passes during compilation phases
Compiler->>User: output diagnostics from lints

## Doc Lint Event Processing Sequence Diagram
### (New sub-flow for documentation lints, added by PR #16144)

```mermaid
sequenceDiagram
participant Pass as "Documentation Pass"
participant CA as check_attrs
participant CD as check_doc
participant P as Parser
participant SM as State Machines
participant CX as LateContext

Pass->>+CA: check doc attributes
CA->>+CD: doc, fragments, valid_idents
CD->>+P: pulldown_cmark::Parser::new(doc, opts, callback)
loop for each event
P->>+CD: (Event, Range<usize>)
CD->>+SM: sm.check(cx, event, range, doc, fragments)
Note right of SM: Accumulate state<br/>e.g., track pending links or paragraph ends
alt lint trigger
SM->>+CX: span_lint_and_then(lint, span, msg, sugg)
end
SM-->>-CD:
end
CD-->>-CA: DocHeaders
CA-->>-Pass:
P-->>-CD:

Note over CD, SM: Single parse, modular event processing
```

\`\`\`

## Additional High-Level Design Aspects
Expand Down Expand Up @@ -90,6 +122,7 @@ This ensures new lints are automatically included when compiling \`clippy_lints\
- **Hooks**: Lints impl methods like \`check_expr\`, \`check_item\` using visitor patterns or queries via \`cx\`.
- **Groups and Levels**: Lints assigned to categories (correctness, style, etc.) auto-grouped by \`LintListBuilder\`; levels (Allow, Warn, Deny).
- **Fixes**: Use \`rustfix::diagnostics::Diagnostic::fix` for auto-fixes via \`--fix\`.
- **Documentation Lints**: Documentation lints in \`clippy_lints/src/doc/\` are grouped under the \`Documentation\` late lint pass. Markdown parsing of doc comments is performed once per attribute group in the \`check_doc\` function, generating \`pulldown_cmark::Event\`s with byte ranges. Specific lints like \`doc_link_code\` and \`doc_paragraphs_missing_punctuation\` implement state machines as structs (e.g., \`LinkCode\`, \`MissingPunctuation\`) with a \`check\` method that processes each event, maintaining internal state (e.g., pending links, paragraph position) and emitting diagnostics via \`span_lint_and_then\` when patterns match. These are instantiated in \`check_doc\` and called in its main event loop. This design, refined in [PR #16144](https://github.com/rust-lang/rust-clippy/pull/16144), ensures efficient single-pass analysis and modularity. New doc lints should adopt this event-driven pattern.

### Edge Cases and Extensibility

Expand Down
59 changes: 59 additions & 0 deletions pr-analysis-16144.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# PR #16144: Workflow Design Impact Analysis

## Affected Workflows
- Workflow 5 (lint-development): Justification - The PR introduces a new pattern for implementing documentation lints by refactoring `doc_link_code` and `doc_paragraphs_missing_punctuation` into state machines that process events from a centralized markdown parser in `check_doc` (in `clippy_lints/src/doc/mod.rs`). This optimizes parsing (once per doc comment) and modularizes lint logic, impacting the documented lint implementation design in workflow 5. Evidence from PR changes to lint files and tests, matching relevant_files like \`clippy_lints/src/\` and \`tests/ui/\`.

No other workflows are affected, as changes are internal to specific lint implementations and do not alter scaffolding, registration, testing execution, or other high-level flows.

## Workflow 5 Analysis
### Summary of design changes
The PR affects the \`clippy_lints\` component, specifically the implementation pattern for documentation lints in \`src/doc/\`. Previously, \`doc_link_code\` logic was inline in \`mod.rs\` with its own event processing via \`check_for_code_clusters\`, and \`doc_paragraphs_missing_punctuation\` performed its own markdown parsing. The PR extracts \`doc_link_code\` to a new file with a \`LinkCode\` state machine struct and refactors the other to a \`MissingPunctuation\` state machine. These now process events from a single parsing in \`check_doc\`, called from the \`Documentation\` late lint pass via \`check_attrs\`.

This changes the design by introducing:
- Centralized event generation to avoid redundant \`pulldown_cmark\` parsing.
- Stateful, event-driven processing for modularity and efficiency.
- Modular files for sub-lint logic within the doc module.

The PR implements this by updating \`mod.rs\` to instantiate the state machines and invoke their \`check\` methods in the event loop of \`check_doc\`, removing old redundant code. Benefits include performance improvement (single parse), easier maintenance, and a reusable pattern for future doc lints. Implications: Developers implementing new doc lints should follow this event-processing state machine pattern; the design doc for workflow 5 has been updated accordingly.

The affected diagram is the \"Integration and Execution Sequence Diagram\", where during \"execute lint passes during compilation phases\", for doc lints, the flow now includes event dispatching to state machines. Below is a diagram highlighting the differences in the doc lint processing sub-flow.

### Diagram showing changes
```mermaid
flowchart TD
subgraph before[\"Before PR - Redundant Processing (to be removed)\"]
Parse1[pulldown_cmark Parser in check_for_code_clusters]
Parse2[pulldown_cmark Parser in doc_paragraphs_missing_punctuation::check]
Inline[Inline state in mod.rs for doc_link_code]
style Parse1 fill:#ffcccc,stroke:#ff0000
style Parse2 fill:#ffcccc,stroke:#ff0000
style Inline fill:#ffcccc,stroke:#ff0000
end

subgraph changed[\"Modified - Central Dispatch (yellow)\"]
CheckDoc[check_doc function in mod.rs]
EventLoop[event loop over events]
Dispatch[dispatches to state machines via .check(event)]
style CheckDoc fill:#ffff99,stroke:#ffff00
style EventLoop fill:#ffff99,stroke:#ffff00
style Dispatch fill:#ffff99,stroke:#ffff00
end

subgraph after[\"After PR - Additions (green)\"]
SingleParse[single pulldown_cmark Parser in check_doc]
SM1[LinkCode state machine - new file doc_link_code.rs]
SM2[MissingPunctuation state machine - refactored file]
Modul[Modular state accumulation across events]
style SingleParse fill:#ccffcc,stroke:#00ff00
style SM1 fill:#ccffcc,stroke:#00ff00
style SM2 fill:#ccffcc,stroke:#00ff00
style Modul fill:#ccffcc,stroke:#00ff00
end

before -.->|replaced by| changed
changed -.->|enhanced with| after

classDef removal fill:#ffcccc,stroke:#ff0000,stroke-width:2px
classDef change fill:#ffff99,stroke:#ffff00,stroke-width:2px
classDef addition fill:#ccffcc,stroke:#00ff00,stroke-width:2px
```