Skip to content

Claim slices 5a and 8a: shared tags predicates and Clojure inert regions after #349 #389

Open

Description

@tag-und-nacht

Continuation of #349, following the maintainer's review. I'd like to claim slices 5a and 8a from Adding a language: common stays common.

This issue tracks the follow-up work; neither slice expands the scope of #349. The existing shared-mechanism issues remain authoritative: #355 for predicates and #357 / #380 for inert regions.

Slice 5a: shared tags-pass predicates

  • Coordinate with Tags pass: evaluate #eq?/#any-of?/#not-any-of? so keyword tables move out of C++ #355 and reuse the string-predicate evaluator in src/ingest_astquery.h to evaluate #eq?, #any-of?, and #not-any-of? in the shared tags pass. No regex predicates in the tags pass.
  • Migrate Elixir's keyword-head table first, then Clojure's defining-head classification and special-form exclusions into tags.scm, using shared capture names.
  • Remove the corresponding temporary C++ keyword tables rather than add another language-specific predicate loop.

Acceptance: red-first fixtures for each predicate, existing-language byte identity, and preserved Clojure definition kinds / call exclusions. Refresh the parser-version mirror and extraction hash together using the integration train's version guidance.

Slice 8a: Clojure on the shared inert-region mechanism

Start after both #349 and #380 land on main. Reuse the shared ancestor walker / language adapter introduced by #380, replacing clojureInert rather than creating another suppression path.

Cover quoted, syntax-quoted, reader-discarded, and (comment ...) forms, including live ~ / ~@ holes and nested boundaries. Inert captured call sites must be counted through the shared declined-reference accounting, with no call edges or target candidates; live expressions retain their real lexical context.

Acceptance: red-first inert/live-hole and nested-boundary fixtures, retained quote/discard/comment negatives, explicit declined-count checks, cold/warm parity, deterministic XML, and byte-identical Elixir and other unaffected-language output.

The slices can land in separate focused PRs. The shared qualified-call refusal (slice 6a) and namespace resolver (slice 6b) are outside this issue.

Activity

  1. joyful-ii-V-I commented on Oct 14, 2026

    @joyful-ii-V-I
    Collaborator

    @tag-und-nacht thank you again for #349. It was a model language PR: data on the shared mechanisms, no Clojure code in graph.h, a pinned str/join known-gap arm instead of a local guard, a slice pointer above each temporary table, and a clean malformed-input and ASan run. On our side it changed no other language's output (68 commands across 14 repositories, all byte-identical), and --clones showed no new group. Both slices are yours. Separate PRs suit us well.

    5a: tags-pass predicates (#355)

    • Start points: the tags match loop in captureTagsFacts (src/ingest_sidecap.h, the ts_query_cursor_next_match loop) applies no predicates today. passesPredicates (src/ingest_astquery.h) handles #eq?/#not-eq?/#match?, but not #any-of?/#not-any-of?, and it brings in the regex table. A small string-only evaluator shared by both callers (no regex in the tags pass, as you wrote) keeps the tags pass cheap.
    • Order: Elixir first (elixirFunctionKeyword and elixirMetadataAttribute in ingest_elixir.h, and its clone macroBodyKeyword in ingest_relations.h), then Clojure (clojureDefinitionShape and the special-form list in clojureKeepCapture). clojureDeclarationMethod ("inside a list headed X") is not expressible as a predicate and can stay.
    • Gates: elixircheck, elixirnamearitycheck, clojurecheck, macroedgecheck, qschemetripcheck. Add one red-first arm per predicate.

    8a: Clojure inert regions

    For both: update the CONTRIBUTING map rows (family 5 and family 8, state and slice cells) in the same PR. Before you open each PR, run ripwire . --quality-delta=origin/main..HEAD (it should gate 0) and ripwire src --clones (the folded group should be gone). For the byte-identity evidence, follow the "Definition of done" item 2: the same argv list run against main and your head with --no-cache, covering the map, --deps, --skipped, and --callers/--callees on the touched symbols. Use the Elixir and Clojure fixtures plus at least one real repository per touched language, plus one repository in an untouched language. Post the argv list and the empty diff. Bump kParserVer and its mirror above main's value. We renumber at merge.

  2. tag-und-nacht commented on Oct 14, 2026

    @tag-und-nacht
    ContributorAuthor

    @joyful-ii-V-I I may be slow to address this and #390. I'll be busy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions