Skip to content

Lisp/Racket reader macros (quote, quasiquote, unquote) produce phantom symbol definitions #2004

Description

@Widthdom

Summary

The Lisp extractor at SymbolExtractor.Lisp.cs detects quoted forms like 'symbol, `symbol, ,symbol as bareword symbols because IsQuotedLispForm (line 94) checks only for a quote character at the opening paren, not quote prefixes on individual datums. When code contains 'defun, `let-binding, or ,unquoted-var, the extractor calls TryCreateLispSymbol on the name after the prefix (e.g. defun from 'defun), emitting false-positive function definitions. This breaks symbol navigation in metaprogramming-heavy codebases (macros, quasiquoted templates) because the extractor confuses quoted references with definitions.

Where

  • src/CodeIndex/Indexer/Symbols/SymbolExtractor.Lisp.cs:90-102 (main loop, quoted-form detection)
  • src/CodeIndex/Indexer/Symbols/SymbolExtractor.Lisp.cs:178-179 (definition name extraction; SkipLispQuotePrefixes called here but NOT in main loop)

Suggested approach

  1. In the main loop (Lisp.cs:90-102), call SkipLispQuotePrefixes(maskedLine, cursor + 1) before checking if TryReadLispListHead should be invoked
  2. If a quote prefix is found, skip the entire quoted datum (do not treat it as a symbol definition), and advance cursor past the closing paren
  3. Refactor IsQuotedLispForm to return both a boolean and an adjusted cursor position; update call sites to use the adjusted position
  4. Add a blacklist of known Lisp special forms that should never be treated as definitions even without quotes: quote, quasiquote, unquote, function, eval-when, etc.
  5. Write regression tests with '(defun foo ...), `(let ((x 1)) ...), and ,,(expand-macro ...) to confirm they emit zero symbols (or only the invocation of the macro, not the definition it would produce)
  6. Extend masking in MaskLispCodeLines to also mask string-literal quote prefixes so "'symbol" inside a docstring doesn't trigger quoted-form logic

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions