Extract Semgrep positive pattern dispatch

ober

eda7e9491a3fbe8de272f6cb3ebb3db9bcaefc87

diff --git a/SEMGREP_JERBOA_IMPLEMENTATION.md b/SEMGREP_JERBOA_IMPLEMENTATION.md
index ace5873..010efee 100644
--- a/SEMGREP_JERBOA_IMPLEMENTATION.md
+++ b/SEMGREP_JERBOA_IMPLEMENTATION.md
@@ -511,6 +511,11 @@ Completed in the repo:
   - moved the shared Python import-map and import-line parsing helpers under
     `src/semgrep/engine/py-import-scan.ss` so `scan.ss` no longer carries a
     duplicate import parser implementation
+  - extracted generic positive-pattern clause recursion, `pattern-either`,
+    `pattern-as`, `patterns`, and regex-metavariable stripping into
+    `src/semgrep/engine/positive-dispatch.ss`, leaving `scan.ss` with the
+    language-specific pattern callback ownership instead of the duplicated
+    dispatch machinery
   - exported shared Python line-assignment analysis from
     `src/semgrep/engine/py-constant-prop.ss` so remaining Python fallbacks in
     `scan.ss` can reuse one assignment-info implementation
@@ -531,9 +536,10 @@ Remaining Phase 0 work:
 - Continue splitting `src/semgrep/scan.ss` into engine, targeting, text-mode,
   structural dispatch, taint, and result/output-adjacent modules. The Python
   constant-propagation, f-string/interpolated, return/list, and import
-  special-case fallback surfaces are now out; the next meaningful cuts are the
-  larger language dispatch, import-map/shared textual helper ownership, and
-  taint sections.
+  special-case fallback surfaces are now out, and the duplicated positive-entry
+  dispatch core is out too; the next meaningful cuts are the remaining larger
+  language-specific callback ownership in `scan.ss`, shared textual helper
+  ownership, and taint sections.
 - Run broader upstream sweeps and grow the expected-fail baselines from real
   sampled data instead of one narrow seed run.
 
diff --git a/lib/semgrep/engine/positive-dispatch.sls b/lib/semgrep/engine/positive-dispatch.sls
new file mode 100644
index 0000000..83ddd9f
--- /dev/null
+++ b/lib/semgrep/engine/positive-dispatch.sls
@@ -0,0 +1,89 @@
+#!chezscheme
+;;; Generated by jerbuild — DO NOT EDIT
+;;; Source: src/semgrep/engine/positive-dispatch.ss
+
+(library (semgrep engine positive-dispatch)
+  (export
+    positive-pattern-entry?
+    pattern-inside-clause?
+    findings-without-metavars
+    scan-positive-entry-dispatch)
+  (import
+    (except (chezscheme) make-hash-table hash-table? sort sort!
+     printf fprintf format path-extension path-absolute?
+     with-input-from-string with-output-to-string iota \x31;+
+     \x31;- partition make-date make-time meta atom?)
+    (except (jerboa prelude) meta atom?)
+    (semgrep match structural) (semgrep result)
+    (semgrep result findings))
+  (def (alist-ref/default xs key default)
+       (let ([found (assoc key xs)])
+         (if found (cdr found) default)))
+  (def (positive-pattern-entry? entry)
+       (case (car entry)
+         [(pattern-regex pattern pattern-either pattern-as patterns)
+          #t]
+         [else #f]))
+  (def (pattern-inside-clause? entry)
+       (eq? (car entry) 'pattern-inside))
+  (def (finding-without-metavars finding)
+       (finding-with-extra
+         finding
+         (remove-extra-key 'metavars (finding-extra finding))))
+  (def (findings-without-metavars findings)
+       (map finding-without-metavars findings))
+  (def (finding-add-as-binding finding as-var source)
+       (let* ([name (normalize-metavariable-name as-var)]
+              [binding (make-metavariable-binding name
+                         (source-slice
+                           source
+                           (finding-start-offset finding)
+                           (finding-end-offset finding))
+                         (finding-start-offset finding)
+                         (finding-end-offset finding)
+                         (finding-start-line finding)
+                         (finding-start-col finding)
+                         (finding-end-line finding)
+                         (finding-end-col finding))]
+              [extra (finding-extra finding)]
+              [metavars (finding-metavars finding)]
+              [extra-without-metavars (remove-extra-key 'metavars extra)])
+         (finding-with-extra
+           finding
+           (cons
+             (cons 'metavars (cons (cons name binding) metavars))
+             extra-without-metavars))))
+  (def (scan-positive-entry-dispatch entry source regex-captures? scan-pattern-regex
+         scan-pattern scan-patterns)
+       (case (car entry)
+         [(pattern-regex)
+          (let ([findings (scan-pattern-regex (cdr entry))])
+            (if regex-captures?
+                findings
+                (findings-without-metavars findings)))]
+         [(pattern) (scan-pattern (cdr entry))]
+         [(pattern-either)
+          (apply
+            append
+            (map (lambda (subentry)
+                   (cond
+                     [(positive-pattern-entry? subentry)
+                      (scan-positive-entry-dispatch subentry source regex-captures? scan-pattern-regex
+                        scan-pattern scan-patterns)]
+                     [(pattern-inside-clause? subentry)
+                      (scan-positive-entry-dispatch (cdr subentry) source regex-captures?
+                        scan-pattern-regex scan-pattern scan-patterns)]
+                     [else '()]))
+                 (cdr entry)))]
+         [(patterns) (scan-patterns (cdr entry))]
+         [(pattern-as)
+          (let ([as-var (alist-ref/default (cdr entry) 'as #f)]
+                [subentry (alist-ref/default (cdr entry) 'entry #f)])
+            (map (lambda (finding)
+                   (finding-add-as-binding finding as-var source))
+                 (scan-positive-entry-dispatch subentry source regex-captures? scan-pattern-regex
+                   scan-pattern scan-patterns)))]
+         [else
+          (error 'scan-positive-entry-dispatch
+            "unsupported positive pattern entry"
+            (car entry))])))
diff --git a/lib/semgrep/scan.sls b/lib/semgrep/scan.sls
index 58cd3e8..1784417 100644
--- a/lib/semgrep/scan.sls
+++ b/lib/semgrep/scan.sls
@@ -26,6 +26,7 @@
    (semgrep engine js-vardef-scan)
    (semgrep engine js-decorator-scan)
    (semgrep engine markup-scan)
+   (semgrep engine positive-dispatch)
    (semgrep engine py-constant-scan)
    (semgrep engine py-cp-scan)
    (semgrep engine py-constant-prop)
@@ -14716,558 +14717,441 @@
                 (scan-positive-pattern-entry rule entry language path
                   source target-root))
               (rule-pattern rule))))
-  (def (finding-without-metavars finding)
-       (finding-with-extra
-         finding
-         (remove-extra-key 'metavars (finding-extra finding))))
-  (def (findings-without-metavars findings)
-       (map finding-without-metavars findings))
   (def (scan-positive-pattern-entry rule entry language path
          source target-root)
        (scan-positive-pattern-entry* rule entry language path
          source target-root #t))
-  (def (scan-positive-pattern-entry* rule entry language path source target-root
-         regex-captures?)
-       (case (car entry)
-         [(pattern-regex)
-          (let ([findings (scan-regex-pattern-with-line-anchors
-                            rule
-                            path
-                            source
-                            (cdr entry))])
-            (if regex-captures?
-                findings
-                (findings-without-metavars findings)))]
-         [(pattern)
-          (or (and (typescript-like-language? language)
-                   (scan-typescript-decorated-field-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-decorated-async-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-vardef-assign-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (scan-string-key-object-pattern
-                rule
-                path
-                source
-                (cdr entry))
-              (and (string=? language "json")
-                   (scan-json-key-value-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-object-type-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-req-param-assignment-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-mongo-where-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-import-equals-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-dependencies-field-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-constructor-typed-param-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-arrow-assignment-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-arrow-object-param-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-member-ellipsis-plus-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-string-concat-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-template-sql-expression-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-new-function-sequence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-imported-bar-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-import-equivalence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-small-pattern-fallbacks
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-imported-member-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-resolved-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-simple-element-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-style-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-attribute-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-this-props-destructure-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-function-props-source-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-react-create-element-spread-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-record-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-pattern-fallbacks rule path source
-                     (cdr entry) '()))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-ellipsis-only-pattern rule path source
-                     target-root (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-bare-metavariable-pattern rule path source
-                     target-root (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-method-sequence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-fstring-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-loop-else-constant-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-and-or-string-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-django-redirect-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (scan-python-import-local-pattern rule language path source target-root (cdr entry)
-                scan-structural-pattern)
-              (scan-symbolic-propagation-pattern rule language path source
-                (cdr entry))
-              (and (xml-language? language)
-                   (scan-xml-pattern rule path source (cdr entry)))
-              (and (yaml-language? language)
-                   (scan-yaml-duplicate-id-range-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (c-language? language)
-                   (scan-c-negated-cast-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (scan-structural-pattern rule language path source
-                target-root (cdr entry)))]
-         [(pattern-either)
-          (apply
-            append
-            (map (lambda (subentry)
-                   (cond
-                     [(positive-pattern-entry? subentry)
-                      (scan-positive-pattern-entry* rule subentry language path source target-root
-                        regex-captures?)]
-                     [(pattern-inside-clause? subentry)
-                      (scan-positive-pattern-entry* rule (cdr subentry) language path source
-                        target-root regex-captures?)]
-                     [else '()]))
-                 (cdr entry)))]
-         [(patterns)
-          (scan-patterns-clauses* rule (cdr entry) language path
-            source target-root regex-captures?)]
-         [(pattern-as)
-          (let ([as-var (alist-ref/default (cdr entry) 'as #f)]
-                [subentry (alist-ref/default (cdr entry) 'entry #f)])
-            (map (lambda (finding)
-                   (finding-add-as-binding finding as-var source))
-                 (scan-positive-pattern-entry* rule subentry language path
-                   source target-root regex-captures?)))]
-         [else
-          (error 'scan-string
-            "unsupported positive pattern entry"
-            (car entry))]))
+  (def (scan-positive-pattern-entry* rule entry language path
+         source target-root regex-captures?)
+       (def (scan-pattern-regex pattern)
+            (scan-regex-pattern-with-line-anchors
+              rule
+              path
+              source
+              pattern))
+       (def (scan-pattern pattern)
+            (or (and (typescript-like-language? language)
+                     (scan-typescript-decorated-field-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-decorated-async-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-vardef-assign-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (scan-string-key-object-pattern rule path source pattern)
+                (and (string=? language "json")
+                     (scan-json-key-value-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-object-type-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-req-param-assignment-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-mongo-where-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-import-equals-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-dependencies-field-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-constructor-typed-param-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-arrow-assignment-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-arrow-object-param-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-member-ellipsis-plus-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-string-concat-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-template-sql-expression-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-new-function-sequence-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-imported-bar-call-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-import-equivalence-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-small-pattern-fallbacks
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-imported-member-call-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-resolved-call-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-jsx-simple-element-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-jsx-style-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-jsx-attribute-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-this-props-destructure-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-function-props-source-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-react-create-element-spread-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-record-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-pattern-fallbacks rule path source
+                       pattern '()))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-ellipsis-only-pattern rule path source
+                       target-root pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-bare-metavariable-pattern rule path
+                       source target-root pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-method-sequence-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-fstring-call-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-loop-else-constant-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-and-or-string-call-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (symbolic-python-like-language? language)
+                     (scan-python-django-redirect-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (scan-python-import-local-pattern rule language path source target-root pattern
+                  scan-structural-pattern)
+                (scan-symbolic-propagation-pattern rule language path
+                  source pattern)
+                (and (xml-language? language)
+                     (scan-xml-pattern rule path source pattern))
+                (and (yaml-language? language)
+                     (scan-yaml-duplicate-id-range-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (c-language? language)
+                     (scan-c-negated-cast-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (scan-structural-pattern rule language path source
+                  target-root pattern)))
+       (def (scan-patterns clauses)
+            (scan-patterns-clauses* rule clauses language path source
+              target-root regex-captures?))
+       (scan-positive-entry-dispatch entry source regex-captures? scan-pattern-regex
+         scan-pattern scan-patterns))
   (def (scan-positive-pattern-entry-with-bindings* rule entry language path source target-root regex-captures?
          initial-bindings)
-       (case (car entry)
-         [(pattern-regex)
-          (let ([findings (scan-regex-pattern-with-line-anchors
-                            rule
-                            path
-                            source
-                            (cdr entry))])
-            (if regex-captures?
-                findings
-                (findings-without-metavars findings)))]
-         [(pattern)
-          (or (and (typescript-like-language? language)
-                   (scan-typescript-decorated-field-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-decorated-async-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-vardef-assign-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (string=? language "json")
-                   (scan-json-key-value-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-object-type-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-req-param-assignment-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-mongo-where-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (typescript-like-language? language)
-                   (scan-typescript-import-equals-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-dependencies-field-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-constructor-typed-param-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-arrow-assignment-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-arrow-object-param-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-member-ellipsis-plus-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-string-concat-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-template-sql-expression-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-new-function-sequence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-imported-bar-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-import-equivalence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-small-pattern-fallbacks
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-imported-member-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (javascript-like-language? language)
-                   (scan-javascript-resolved-call-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-simple-element-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-style-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-jsx-attribute-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-this-props-destructure-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-function-props-source-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-react-create-element-spread-pattern-with-bindings rule path source (cdr entry) initial-bindings))
-              (and (javascript-like-language? language)
-                   (scan-javascript-record-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-pattern-fallbacks rule path source
-                     (cdr entry) initial-bindings))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-ellipsis-only-pattern rule path source
-                     target-root (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-bare-metavariable-pattern-with-bindings rule path source target-root (cdr entry)
-                     initial-bindings))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-method-sequence-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-fstring-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-loop-else-constant-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-and-or-string-call-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (and (or (string=? language "python")
-                       (string=? language "python2")
-                       (string=? language "python3")
-                       (string=? language "py"))
-                   (scan-python-django-redirect-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (scan-python-import-local-pattern-with-bindings rule language path source target-root (cdr entry)
-                initial-bindings scan-structural-pattern-with-bindings)
-              (scan-symbolic-propagation-pattern rule language path source
-                (cdr entry))
-              (and (c-language? language)
-                   (scan-c-negated-cast-pattern
-                     rule
-                     path
-                     source
-                     (cdr entry)))
-              (scan-structural-pattern-with-bindings rule language path source target-root (cdr entry)
-                initial-bindings))]
-         [(pattern-either)
-          (apply
-            append
-            (map (lambda (subentry)
-                   (cond
-                     [(positive-pattern-entry? subentry)
-                      (scan-positive-pattern-entry-with-bindings* rule subentry language path source target-root
-                        regex-captures? initial-bindings)]
-                     [(pattern-inside-clause? subentry)
-                      (scan-positive-pattern-entry-with-bindings* rule (cdr subentry) language path source
-                        target-root regex-captures? initial-bindings)]
-                     [else '()]))
-                 (cdr entry)))]
-         [(patterns)
-          (scan-patterns-clauses-with-bindings* rule (cdr entry) language path source target-root
-            regex-captures? initial-bindings)]
-         [(pattern-as)
-          (let ([as-var (alist-ref/default (cdr entry) 'as #f)]
-                [subentry (alist-ref/default (cdr entry) 'entry #f)])
-            (map (lambda (finding)
-                   (finding-add-as-binding finding as-var source))
-                 (scan-positive-pattern-entry-with-bindings* rule subentry language path source target-root
-                   regex-captures? initial-bindings)))]
-         [else
-          (error 'scan-string
-            "unsupported positive pattern entry"
-            (car entry))]))
-  (def (positive-pattern-entry? entry)
-       (case (car entry)
-         [(pattern-regex pattern pattern-either pattern-as patterns)
-          #t]
-         [else #f]))
-  (def (pattern-inside-clause? entry)
-       (eq? (car entry) 'pattern-inside))
+       (def (scan-pattern-regex pattern)
+            (scan-regex-pattern-with-line-anchors
+              rule
+              path
+              source
+              pattern))
+       (def (scan-pattern pattern)
+            (or (and (typescript-like-language? language)
+                     (scan-typescript-decorated-field-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-decorated-async-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-vardef-assign-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (string=? language "json")
+                     (scan-json-key-value-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-object-type-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-req-param-assignment-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-mongo-where-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (typescript-like-language? language)
+                     (scan-typescript-import-equals-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-dependencies-field-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-constructor-typed-param-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)
+                     (scan-javascript-arrow-assignment-pattern
+                       rule
+                       path
+                       source
+                       pattern))
+                (and (javascript-like-language? language)