# XLIDE VBA Lint Suppression Comments

Status: proposed roadmap contract, not implemented behavior.

Purpose: define a deterministic, VBA-compatible comment syntax for suppressing
XLIDE lint diagnostics. These comments are ordinary VBA comments, so they do not
change how Excel/VBE compiles or runs the project.

## Principles

- Suppressions affect XLIDE diagnostics only.
- Suppressions never make invalid VBA valid.
- Suppressions are lexical and deterministic; no control-flow interpretation.
- Prefer suppressing one diagnostic code over suppressing `all`.
- Malformed directives should produce a directive diagnostic instead of being
  guessed.
- Documentation comments beginning with `'''` are not suppression directives.

## Directive Form

A directive is a single-apostrophe VBA comment whose comment body starts with
`@xlide-lint`.

```vba
' @xlide-lint-disable-next-line argument-count -- legacy macro signature
```

Spacing after the apostrophe is optional. The directive parser should treat
these as equivalent:

```vba
'@xlide-lint-disable-next-line argument-count
' @xlide-lint-disable-next-line argument-count
```

The first implementation should not recognize `Rem` directives. Supporting
`Rem` can be added later if it has a deterministic lexer rule and tests.

## Diagnostic Code Lists

Each suppression directive accepts either `all` or a comma-separated list of
diagnostic codes.

```vba
' @xlide-lint-disable-next-line all
' @xlide-lint-disable-next-line argument-count,argument-type-mismatch
```

If no code list is supplied, the directive means `all`.

```vba
' @xlide-lint-disable-next-line
```

Reasons are optional free text after `--`.

```vba
' @xlide-lint-disable-next-member non-callable-call -- VBE macro shim
```

Unknown diagnostic codes should not suppress anything. They should eventually
produce a yellow directive diagnostic.

## Module Suppression

Use `disable-file` to suppress diagnostics for the entire module.

```vba
' @xlide-lint-disable-file all -- generated module
Option Explicit

Public Sub GeneratedEntryPoint()
End Sub
```

Rules:

- `disable-file` applies to the whole module.
- It should appear before the first non-comment, non-attribute source line.
- If it appears later, XLIDE should emit a directive diagnostic and not guess.

## Member Suppression

Use `disable-next-member` directly above a top-level declaration.

```vba
' @xlide-lint-disable-next-member argument-count -- called by external host
Public Sub RunReport(ByVal reportId As String)
    BuildReport reportId, , True
End Sub
```

The directive applies to the next top-level member block:

- `Sub ... End Sub`
- `Function ... End Function`
- `Property Get/Let/Set ... End Property`
- `Type ... End Type`
- `Enum ... End Enum`

It does not apply to an arbitrary statement inside a procedure. Use a block
suppression for that.

## Line Suppression

Use `disable-next-line` before the line to suppress.

```vba
' @xlide-lint-disable-next-line assignment-type-mismatch -- runtime validated
total = "100"
```

Use `disable-line` as a trailing comment on the same physical line.

```vba
total = "100" ' @xlide-lint-disable-line assignment-type-mismatch
```

Rules:

- `disable-next-line` applies only to the next physical source line.
- `disable-line` applies only to the physical line containing the directive.
- Line directives do not extend over continued logical lines unless explicitly
  implemented and tested later.

## Arbitrary Block Suppression

Use paired block directives for a lexical region.

```vba
' @xlide-lint-disable-block argument-type-mismatch -- imported legacy block
total = InvoiceTotal("100", 0.08)
caption = BuildCaption(1)
' @xlide-lint-enable-block argument-type-mismatch
```

Rules:

- Block suppression starts after the `disable-block` directive line.
- Block suppression ends before the matching `enable-block` directive line.
- Block directives are lexical by source position, not by VBA control flow.
- Unbalanced block directives should produce a directive diagnostic.
- Nested blocks should be supported only after explicit tests define the stack
  behavior.

## Examples

Suppress an entire generated module:

```vba
' @xlide-lint-disable-file all -- generated by accounting export
Option Explicit

Public Sub EntryPoint()
End Sub
```

Suppress one procedure:

```vba
' @xlide-lint-disable-next-member non-callable-call -- host callback shape
Public Sub Workbook_Open()
    Start
End Sub
```

Suppress one line:

```vba
Set total = 1 ' @xlide-lint-disable-line set-requires-object -- VBE canary pending
```

Suppress an imported block:

```vba
' @xlide-lint-disable-block all -- vendor code, do not edit
GoSub LegacyPath
Return
' @xlide-lint-enable-block all
```

## Non-Goals

- No fuzzy matching of directive names.
- No suppression from documentation comments beginning with `'''`.
- No automatic suppression because a file or procedure name looks generated.
- No hidden suppression state outside source comments.
- No change to compile, runtime, test-runner, or oracle behavior.

## Implementation Checklist

1. Add a pure directive scanner that consumes tokenized comments.
2. Normalize directive spans into file, member, line, and block scopes.
3. Filter diagnostics after diagnostics are produced, preserving suppressed
   counts for audit/reporting.
4. Add directive diagnostics for malformed scopes, unknown codes, late
   `disable-file`, and unbalanced blocks.
5. Add fixture tests for every scope and edge case before enabling the feature.
