From 3b4ff62737c368af865eb0239969ca23eef8c4d1 Mon Sep 17 00:00:00 2001 From: Ryan Atkinson Date: Wed, 16 Sep 2026 10:05:26 -0400 Subject: [PATCH] fix: keep a pair around a relational < chain whose printed form would re-lex as type arguments --- CLAUDE.md | 6 +- benches/js/corpus_audit.ts | 6 + crates/tsv_debug/src/audit/vacuity.rs | 46 +- .../src/cli/commands/blank_audit_known.txt | 9 +- .../tsv_debug/src/cli/commands/paren_audit.rs | 420 +- crates/tsv_svelte_compile/src/build.rs | 3 + crates/tsv_svelte_compile/src/erase.rs | 4 + .../tsv_svelte_compile/src/store_rewrite.rs | 4 + .../tsv_svelte_compile/src/template_value.rs | 4 + crates/tsv_ts/src/ast/internal/expressions.rs | 24 + crates/tsv_ts/src/parser/expression.rs | 66 +- .../tsv_ts/src/parser/expression_lookahead.rs | 58 +- .../tsv_ts/src/parser/expression_type_args.rs | 535 +- crates/tsv_ts/src/parser/mod.rs | 24 + crates/tsv_ts/src/printer/needs_parens.rs | 39 + deno.json | 3 +- docs/conformance_prettier.md | 1 + docs/conformance_prettier_ts.md | 206 + .../README.md | 22 + .../expected.json | 2165 +++++ .../input.svelte | 28 + .../output_prettier.svelte | 28 + .../README.md | 27 + .../audit_signature.txt | 29 + .../expected.json | 636 ++ .../input.svelte | 22 + .../output_prettier.svelte | 21 + .../README.md | 32 + .../expected.json | 973 ++ .../input.svelte | 26 + .../output_prettier.svelte | 26 + .../README.md | 30 + .../audit_signature.txt | 63 + .../expected.json | 4806 ++++++++++ .../input.svelte | 54 + .../output_prettier.svelte | 54 + .../unformatted_ours_operand_shell.svelte | 54 + .../unformatted_ours_region_break.svelte | 60 + .../relational_lt_vs_type_args/expected.json | 8434 +++++++---------- .../relational_lt_vs_type_args/input.svelte | 25 +- .../unformatted_asi.svelte | 25 +- .../unformatted_compact.svelte | 25 +- .../unformatted_operand_shell.svelte | 114 + tests/instantiation_follow_parens.rs | 26 +- 44 files changed, 13786 insertions(+), 5477 deletions(-) create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/README.md create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/expected.json create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/input.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/output_prettier.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/README.md create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/audit_signature.txt create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/expected.json create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/input.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/output_prettier.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/README.md create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/expected.json create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/input.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/output_prettier.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/README.md create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/audit_signature.txt create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/expected.json create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/input.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/output_prettier.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_operand_shell.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_region_break.svelte create mode 100644 tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_operand_shell.svelte diff --git a/CLAUDE.md b/CLAUDE.md index ea7fab8d5..65cb51e89 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -216,7 +216,11 @@ deno task paren:audit # authoring-independence over redundant PAR # (`a ?? b ?? c`) must format identically to the twin prettier rebalances it from # (`a ?? (b ?? c)`). Zero-tolerance, no ratchet — a redundant paren carries no authoring # signal, so every divergence is a bug. The class is invisible on every paren-free -# authoring, which is every authoring a formatted corpus holds (bug539) +# authoring, which is every authoring a formatted corpus holds (bug539). Also the +# relational `<`…`>` chain: `a < X > c` against `(a < X) > c` and `a < (X) > c`, the +# redundant shells that can move its byte-read type-argument pair. `--require-relational` +# (passed here, not by `audit:corpus`) adds a floor on relational sites, which only +# tests/fixtures holds — a narrowed run drops it deno task fuzz:audit # seeded mutational fuzzer (fixed seed/iterations): no-panic + idempotency + structural reparse (node loss HARD, skeleton divergence soft); its token dictionary carries `// prettier-ignore`, the only standing instrument that composes a freeze with a comment or a paren shell deno task swallow:audit # `//` line comment swallowing following output-line content (also over real code via audit:corpus) deno task comments:audit # print-once comment ledger: DROPPED / DOUBLE-PRINTED comments diff --git a/benches/js/corpus_audit.ts b/benches/js/corpus_audit.ts index 6634feff9..2dbd18d47 100644 --- a/benches/js/corpus_audit.ts +++ b/benches/js/corpus_audit.ts @@ -41,6 +41,12 @@ * sweep below. Real code carries twice the fixture corpus's chains, and the class it gates is * one a corpus of formatted code cannot otherwise show: the paren-nested authoring is exactly * what tsv's own output normalizes away (docs/audits.md §Paren-Authoring Independence). + * Run WITHOUT `--require-relational`, which `deno task paren:audit` (the fixture-tree gate) + * passes: that flag is the audit's per-class vacuity floor over its relational `<`…`>` sites, + * and it is a claim about the SEED SET rather than about the audit. Nobody writes `a < b > c` + * in real code, so both relational rows are legitimately 0 here and a floor over them would + * fail a clean run. This leg still grades every relational site it finds; it holds only the + * unconditional total floor. * - `census_audit` — every comment interior the author wrote survives formatting, compared as raw * input-vs-output trivia multisets by the audit's own scanners. All dirs. This is the leg whose * yield is external corpora *by its own design* — over `tests/fixtures` it is a tripwire, and its diff --git a/crates/tsv_debug/src/audit/vacuity.rs b/crates/tsv_debug/src/audit/vacuity.rs index 21ce8fa76..8de04ac78 100644 --- a/crates/tsv_debug/src/audit/vacuity.rs +++ b/crates/tsv_debug/src/audit/vacuity.rs @@ -1,10 +1,10 @@ -//! The **vacuity guard** — the two checks that stop a gate over nothing from +//! The **vacuity guard** — the checks that stop a gate over nothing from //! reading as a green gate. //! //! Every audit's happy path prints a `✓` and exits 0, and so does an audit that //! graded nothing at all: an empty walk, a corpus the parser rejects end to end, -//! a fixture tree that silently shrank. The two layers here answer that at the -//! two scopes a run can have: +//! a fixture tree that silently shrank. The layers here answer that at the +//! scopes a run can have: //! //! - [`check_graded_nonzero`] — **scope-relative**, called unconditionally by //! every corpus-walking audit. Zero graded is vacuous whatever the paths, so it @@ -12,6 +12,9 @@ //! - [`check_formatted_min`] + [`FIXTURES_FORMATTED_MIN`] — **default-corpus**, //! called only on a full default run. It grades a *shrink*, which only a run //! over the committed fixtures tree can be held to. +//! - [`check_required_nonzero`] — **seed-set**, asked for by an explicit flag. +//! It grades a sub-population that only some corpora hold, so the invocation +//! that knows its seeds carry the population is the one that claims it. //! //! Its own module rather than [`super::sweep`]'s (where it was born) because the //! floor is a question about an audit's DENOMINATOR, not about that loop: nine @@ -132,3 +135,40 @@ pub(crate) fn check_graded_nonzero(graded: usize, subject: &str) -> Result<(), C ); Err(CliError::Failed) } + +/// The **seed-set** layer: a floor over a SUB-population, asked for by the `flag` the +/// invocation passes. `subject` names what was counted; `flag` is the switch to drop. +/// +/// [`check_graded_nonzero`] is a claim about the AUDIT — zero graded is vacuous whatever the +/// paths, so no invocation may opt out of it. This one is a claim about the SEED SET: a +/// sub-population an audit grades may be dense in one corpus and legitimately absent from +/// another (a construct real code does not write), and there zero is the correct reading, not +/// a defect. So the floor belongs to whichever invocation knows its seeds carry the +/// population, rather than to the audit — and it is spelled as an explicit flag rather than +/// inferred from the paths, because a flag is greppable and cannot silently mean the wrong +/// thing on a subtree run. +/// +/// A NARROWED run under the flag fails, deliberately and like a ratchet's `:update`: the flag +/// asserts the run covers the population's corpus, which a subtree does not. The message says +/// to drop the flag rather than to widen the paths, since a narrowed run is an ordinary triage +/// run that was never entitled to the claim. +/// +/// # Errors +/// +/// Returns [`CliError::Failed`] (after a user-facing message) when `graded` is 0. +pub(crate) fn check_required_nonzero( + graded: usize, + subject: &str, + flag: &str, +) -> Result<(), CliError> { + if graded > 0 { + return Ok(()); + } + eprintln!( + "Error: vacuous run — 0 {subject}, under {flag}. That flag asserts this run's seeds \ + COVER them, so it belongs only to an invocation whose corpus holds them: a narrowed \ + run, or one over a corpus without them, drops {flag} rather than being graded \ + against a population it does not contain." + ); + Err(CliError::Failed) +} diff --git a/crates/tsv_debug/src/cli/commands/blank_audit_known.txt b/crates/tsv_debug/src/cli/commands/blank_audit_known.txt index 7872ee015..77b39e990 100644 --- a/crates/tsv_debug/src/cli/commands/blank_audit_known.txt +++ b/crates/tsv_debug/src/cli/commands/blank_audit_known.txt @@ -20,7 +20,7 @@ # deleted, the blank-DROP class every invariant above is blind to. # # Format: KINDSHAPE -# shapes: 64 +# shapes: 57 NON-IDEMPOTENT (){⟨⟩}). NON-IDEMPOTENT (){⟨⟩}); NON-IDEMPOTENT (⟨⟩IDENT @@ -78,10 +78,3 @@ NON-IDEMPOTENT ␣⟨⟩? NON-IDEMPOTENT ␣⟨⟩IDENT NON-IDEMPOTENT ␣⟨⟩NUM NON-IDEMPOTENT ␣⟨⟩␣ -NODE-LOSS >{⟨⟩IDENT -NODE-LOSS IDENT⟨⟩[ -NODE-LOSS IDENT⟨⟩[. -NODE-LOSS IDENT⟨⟩[\ -NODE-LOSS interface⟨⟩␣ -NODE-LOSS {⟨⟩␣ -NODE-LOSS ␣⟨⟩IDENT diff --git a/crates/tsv_debug/src/cli/commands/paren_audit.rs b/crates/tsv_debug/src/cli/commands/paren_audit.rs index fedf55908..1f5963253 100644 --- a/crates/tsv_debug/src/cli/commands/paren_audit.rs +++ b/crates/tsv_debug/src/cli/commands/paren_audit.rs @@ -1,4 +1,10 @@ -//! Paren-authoring independence audit — same-operator logical re-association. +//! Paren-authoring independence audit — a redundant paren carries no authoring signal, so +//! the two spellings of one document must reach one fixed point. +//! +//! Two site classes, each a rule that reads something the parens change: +//! **same-operator logical re-association** (§Why this exists) and the **relational +//! `<`…`>` chain** (§The relational chain). They share the verdict, the containment and +//! the zero tolerance; only the splice differs. //! //! ## Why this exists //! @@ -48,6 +54,47 @@ //! this keys on the node type and not on an operator list: a `BinaryExpression` (`+`, `&`) //! is NOT re-associable and prettier does not rebalance it. //! +//! ## The relational chain +//! +//! A `>` whose left operand is a `<` gets a paren pair around that operand whenever the +//! `<`…`>` region would re-lex as a type-argument list once printed +//! (`docs/conformance_prettier_ts.md` §Relational chain type-argument parens). That rule +//! reads **bytes** — which head the region opens with, and where its scan stops — so a +//! redundant paren is exactly what can move its answer while leaving the program alone. Two +//! splices per such node, each a pure insertion around a whole operand: +//! +//! - **the chain** — `a < X > c` against `(a < X) > c`, the shell the printer strips, which +//! moves where the region's scan stops; +//! - **the operand** — `a < X > c` against `a < (X) > c`, which moves which HEAD the +//! lookahead dispatches on. +//! +//! The second is where a byte-reading head test is most exposed: a `(` head arm that grades +//! nothing commits every parenthesized operand, so `a < (arr[b - 1]) > c` would take a pair +//! its own paren-free twin does not — and no other standing gate can see that, since each +//! authoring is idempotent on its own and only a twin shows the two fixed points. Nothing +//! re-associates here, but that does not make every twin probeable: what the splice +//! preserves, and what it does not, is stated on +//! [`ParenAuditCommand::twin_is_same_document`]. +//! +//! ## Which invocation carries the relational floor +//! +//! Both classes share the total vacuity floor (`check_graded_nonzero` over every site), which +//! holds on any corpus: a logical chain is ordinary code. The relational rows get a **second, +//! per-class floor** — and it is **opt-in**, spelled `--require-relational`, because a vacuity +//! floor is a claim about the SEED SET rather than about the audit. Nobody writes `a < b > c` +//! in real code: over the `../corpora` snapshot both relational rows are legitimately **0**, +//! and that zero is the corpus's shape, not a class that stopped enumerating. The class lives +//! in the fixture tree (`tests/fixtures/typescript/expressions/binary/relational_*`), so the +//! **fixture-tree gate** — `deno task paren:audit`, which `deno task check` runs — is the one +//! invocation that passes the flag, and the **real-code leg** of `audit:corpus` +//! (`benches/js/corpus_audit.ts`, publish Step 3c) deliberately does not: it grades every +//! class it finds and holds only the total floor. +//! +//! The flag rather than a `paths`-contains-`tests/fixtures` sniff: an explicit switch is +//! greppable and cannot silently mean the wrong thing on a subtree run. A **narrowed** run +//! under the flag fails its floor, like a ratchet's refusal of a narrowed `:update` — the flag +//! asserts the run covers the relational corpus, so a subtree run drops it. +//! //! ## The verdict, and why it is zero-tolerance //! //! `format(variant)` must equal the base `F` — byte for byte, at every site. Unlike the @@ -68,8 +115,12 @@ //! same-operator node, each re-associating one level; the fully right-nested composition of //! those steps is not enumerated. One step is what turns `binary.right` from a leaf into a //! `LogicalExpression`, which is the whole signal. -//! - **Same-operator only**, because that is precisely what prettier rebalances. -//! `a || (b && c)` is a different tree in both formatters and its parens are load-bearing. +//! - **Same-operator only** for the logical class, because that is precisely what prettier +//! rebalances. `a || (b && c)` is a different tree in both formatters and its parens are +//! load-bearing. +//! - **The relational class probes `<` under `>` only** — the one join the rule is keyed +//! on. A `<` under any other operator, and a `>` over any other operand, take no pair, so +//! a shell there is the general redundant-paren question the TODO below names. //! - **A seed bearing a format-ignore directive is skipped** (`source_has_ignore_directive`): //! a frozen region reproduces the inserted parens verbatim, which is correct behavior and //! would read as a divergence. @@ -77,6 +128,13 @@ //! ([`splits_forward_binding_comment`]) — the splice would re-bind a JSDoc cast or a bundler //! annotation, making the twin a different document. Counted in the report, not dropped //! silently. +//! - **A relational site whose twin tsv does not read as the same document is excluded** +//! ([`ParenAuditCommand::twin_is_same_document`], which states why a twin can fail to be +//! one). Counted in the report, not dropped silently. The divergence itself is a parse +//! question, but no parse gate sees these twins — the audit synthesizes them, and no +//! fixture or corpus file holds them — so the count printed here is where they surface. +//! It is not pinned: it is a function of whichever seed set the invocation was handed, so +//! it cannot be held the way a ratchet's snapshot is. //! - **CSS has no expression grammar**, so `.css` seeds hold no sites; the audit's subject //! filter is the Svelte + TypeScript families. //! @@ -115,18 +173,20 @@ use crate::audit::properties::{ }; use crate::audit::repro::{ReproCase, write_repro_case}; use crate::audit::tally::CappedPaths; -use crate::audit::vacuity::check_graded_nonzero; +use crate::audit::vacuity::{check_graded_nonzero, check_required_nonzero}; use crate::cli::CliError; use super::profile::{is_input_invalid_fixture, is_svelte, is_ts_family, resolve_seed_files_named}; -/// Audit whether a same-operator logical chain formats identically to its -/// redundantly-parenthesized twin. +/// Audit whether a chain formats identically to its redundantly-parenthesized twin. /// -/// Prettier rebalances `a op (b op c)` into `(a op b) op c` at parse time, so the two -/// authorings are one document; tsv must reach one fixed point from both. Pure Rust — one -/// format per site, no sidecar. Defaults to `tests/fixtures` when no paths are given; -/// Svelte and TypeScript-family files (a `.css` seed holds no expressions). +/// Two classes. A same-operator LOGICAL chain: prettier rebalances `a op (b op c)` into +/// `(a op b) op c` at parse time, so the two authorings are one document. A RELATIONAL +/// `<`…`>` chain: the rule that parenthesizes its `<` operand reads bytes, so a shell +/// around either the chain or the operand can move its answer. tsv must reach one fixed +/// point from every spelling. Pure Rust — one format per site, no sidecar. Defaults to +/// `tests/fixtures` when no paths are given; Svelte and TypeScript-family files (a `.css` +/// seed holds no expressions). #[derive(FromArgs, Debug)] #[argh(subcommand, name = "paren_audit")] pub struct ParenAuditCommand { @@ -146,6 +206,13 @@ pub struct ParenAuditCommand { #[argh(option, default = "20")] examples: usize, + /// require the relational `<`…`>` classes to have graded a site — the seed-set + /// vacuity floor, for an invocation whose corpus holds the class (the fixture-tree + /// gate). Real code writes no `a < b > c`, so its run drops this; a narrowed run + /// drops it too + #[argh(switch)] + require_relational: bool, + /// file paths, directories, or glob patterns (default: tests/fixtures) #[argh(positional)] paths: Vec, @@ -178,25 +245,64 @@ impl LogicalOp { Self::Nullish => "??", } } +} - const ALL: [Self; 3] = [Self::And, Self::Or, Self::Nullish]; +/// What a site's spliced pair is a twin OF — the audit's classes, one row each in the +/// report. A closed set, so a class with zero sites reads as a corpus gap rather than a +/// pass. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +enum SiteKind { + /// Same-operator logical re-association: `a op b op c` against `a op (b op c)`. + Logical(LogicalOp), + /// A shell around a relational `<`…`>` CHAIN: `a < X > c` against `(a < X) > c`. + RelationalChain, + /// A shell around the `<` OPERAND of such a chain: `a < X > c` against `a < (X) > c`. + /// The direction the region test is most exposed to: a shell there changes which head + /// arm the type-argument lookahead dispatches on, where the chain's own shell only + /// changes where the scan stops. + RelationalOperand, } -/// One re-association site in the formatted base: insert `(` at `open`, `)` at `close`. +impl SiteKind { + fn label(self) -> &'static str { + match self { + Self::Logical(op) => op.label(), + Self::RelationalChain => "< > chain", + Self::RelationalOperand => "< > operand", + } + } + + const ALL: [Self; 5] = [ + Self::Logical(LogicalOp::And), + Self::Logical(LogicalOp::Or), + Self::Logical(LogicalOp::Nullish), + Self::RelationalChain, + Self::RelationalOperand, + ]; + + /// Whether this class is a relational one — the two rows whose own vacuity floor the + /// run checks, so the class cannot quietly stop enumerating. + fn is_relational(self) -> bool { + !matches!(self, Self::Logical(_)) + } +} + +/// One site in the formatted base: insert `(` at `open`, `)` at `close`. #[derive(Clone, Copy, Debug)] struct Site { open: usize, close: usize, - op: LogicalOp, + kind: SiteKind, } -/// A file's enumeration: the sites to probe, and a count of the ones excluded as unsound. -/// The exclusion is counted rather than dropped silently — an audit that quietly stops +/// A file's enumeration: the sites to probe, and counts of the ones excluded as unsound. +/// Each exclusion is counted rather than dropped silently — an audit that quietly stops /// probing a class reads exactly like one that finds nothing in it. #[derive(Default)] struct Sites { probed: Vec, comment_bound: usize, + parse_divergent: usize, } /// Collect every same-operator re-association site in a wire AST. @@ -214,14 +320,11 @@ fn collect_sites(node: &Value, f: &str, map: &Utf16ToByte, out: &mut Sites) { } } Value::Object(fields) => { - if let Some(site) = site_at(fields, map) { - // The one unsound splice, excluded rather than reported: see - // [`splits_forward_binding_comment`]. - if splits_forward_binding_comment(f, site.open) { - out.comment_bound += 1; - } else { - out.probed.push(site); - } + if let Some(site) = logical_site_at(fields, map) { + push_site(site, f, out); + } + for site in relational_sites_at(fields, map).into_iter().flatten() { + push_site(site, f, out); } for (key, value) in fields { // `loc` is the only object-valued field that carries no nodes; skipping it @@ -260,9 +363,71 @@ fn splits_forward_binding_comment(f: &str, at: usize) -> bool { f[..at].trim_end().ends_with("*/") } -/// The site this node is, if it is one: a `LogicalExpression` whose left operand is a -/// `LogicalExpression` with the same operator. -fn site_at(fields: &serde_json::Map, map: &Utf16ToByte) -> Option { +/// Record one site, unless splicing it would re-bind a forward-binding comment — the one +/// unsound splice, excluded rather than reported (see [`splits_forward_binding_comment`]). +fn push_site(site: Site, f: &str, out: &mut Sites) { + if splits_forward_binding_comment(f, site.open) { + out.comment_bound += 1; + } else { + out.probed.push(site); + } +} + +/// The two shells a relational `<`…`>` chain is probed with, when this node is one: a +/// `BinaryExpression` `>` whose left operand is a `BinaryExpression` `<`. +/// +/// Both splices are pure paren insertions around a whole operand, with none of the logical +/// splice's re-association argument to make (nothing moves). Whether tsv's own parser reads +/// each twin as the same document is a separate question, answered per site by +/// [`ParenAuditCommand::twin_is_same_document`]. The pair is what tsv's own +/// relational-chain rule synthesizes and retains +/// (`conformance_prettier_ts.md` §Relational chain type-argument parens), and that rule +/// reads BYTES — which head the `<` region opens with, where the region's scan stops — so +/// both authorings have to reach one fixed point or the rule is keyed on the spelling +/// rather than on the program. +fn relational_sites_at( + fields: &serde_json::Map, + map: &Utf16ToByte, +) -> [Option; 2] { + let none = [None, None]; + let binary_op = |node: &serde_json::Map| -> Option { + (node.get("type")?.as_str()? == "BinaryExpression") + .then(|| node.get("operator")?.as_str().map(str::to_string)) + .flatten() + }; + if binary_op(fields).as_deref() != Some(">") { + return none; + } + let Some(left) = fields.get("left").and_then(Value::as_object) else { + return none; + }; + if binary_op(left).as_deref() != Some("<") { + return none; + } + let span = |node: &serde_json::Map| -> Option { + let open = map.byte(node.get("start")?.as_u64()? as usize)?; + let close = map.byte(node.get("end")?.as_u64()? as usize)?; + (open < close).then_some(Site { + open, + close, + kind: SiteKind::RelationalChain, + }) + }; + let chain = span(left); + let operand = left + .get("right") + .and_then(Value::as_object) + .and_then(span) + .map(|site| Site { + kind: SiteKind::RelationalOperand, + ..site + }); + [chain, operand] +} + +/// The logical site this node is, if it is one: a `LogicalExpression` whose left operand +/// is a `LogicalExpression` with the same operator. +fn logical_site_at(fields: &serde_json::Map, map: &Utf16ToByte) -> Option { if fields.get("type")?.as_str()? != "LogicalExpression" { return None; } @@ -278,7 +443,24 @@ fn site_at(fields: &serde_json::Map, map: &Utf16ToByte) -> Option // parenthesized operand stops before its own `)`. let open = map.byte(left.get("right")?.as_object()?.get("start")?.as_u64()? as usize)?; let close = map.byte(fields.get("end")?.as_u64()? as usize)?; - (open < close).then_some(Site { open, close, op }) + (open < close).then_some(Site { + open, + close, + kind: SiteKind::Logical(op), + }) +} + +/// Drop every positional key from a wire AST, in place — what is left is the tree alone, +/// which is what "the same document" means for a splice that inserts two bytes. +fn strip_positions(node: &mut Value) { + match node { + Value::Array(items) => items.iter_mut().for_each(strip_positions), + Value::Object(fields) => { + fields.retain(|key, _| !matches!(key.as_str(), "start" | "end" | "loc" | "range")); + fields.values_mut().for_each(strip_positions); + } + _ => {} + } } /// Splice one site's redundant parens into the formatted base. @@ -334,7 +516,7 @@ impl Verdict { struct Finding { path: String, offset: usize, - op: LogicalOp, + kind: SiteKind, verdict: Verdict, context: String, /// The first line at which `format(variant)` departs from the base, as @@ -365,8 +547,14 @@ struct Report { panics: CappedPaths, sites: usize, sites_comment_bound: usize, + /// Relational sites whose twin tsv rejects or reads as a different program — see + /// [`ParenAuditCommand::twin_is_same_document`]. + sites_parse_divergent: usize, counts: BTreeMap, - op_counts: BTreeMap<(LogicalOp, Verdict), usize>, + kind_counts: BTreeMap<(SiteKind, Verdict), usize>, + /// Sites enumerated per class, so a class that stops producing them fails its own + /// vacuity floor instead of riding the others' counts. + kind_sites: BTreeMap, findings: Vec, /// Sequence number for `--dump-dir` case directories, so two findings in one file do not /// collide on a name. @@ -378,8 +566,18 @@ impl Report { self.counts.get(&v).copied().unwrap_or(0) } - fn op_count(&self, op: LogicalOp, v: Verdict) -> usize { - self.op_counts.get(&(op, v)).copied().unwrap_or(0) + fn kind_count(&self, kind: SiteKind, v: Verdict) -> usize { + self.kind_counts.get(&(kind, v)).copied().unwrap_or(0) + } + + /// Sites enumerated across the relational classes — the seed-set vacuity floor's + /// denominator, read only by a run that asked for it. + fn relational_sites(&self) -> usize { + self.kind_sites + .iter() + .filter(|(kind, _)| kind.is_relational()) + .map(|(_, n)| n) + .sum() } fn findings_total(&self) -> usize { @@ -398,6 +596,17 @@ impl Report { fn failed(&self) -> bool { self.findings_total() + self.base_non_idempotent.count() + self.panics.count() > 0 } + + /// Whether every vacuity floor THIS run is held to was met — the total always, the + /// relational one only when the invocation asked for it. + /// + /// Stated once because the report's ✓ and the exit code are two readings of it, and a ✓ + /// keyed on a floor the run was never held to is the same doctrine break as one keyed on + /// too few: over real code the relational rows are legitimately zero, and a ✓ withheld + /// there reads as a failure the run did not have. + fn floors_met(&self, require_relational: bool) -> bool { + self.sites > 0 && (!require_relational || self.relational_sites() > 0) + } } impl ParenAuditCommand { @@ -427,9 +636,9 @@ impl ParenAuditCommand { } if self.json { - print_json(&report); + print_json(&report, self.require_relational); } else { - print_human(&report, self.examples); + print_human(&report, self.examples, self.require_relational); } // A base-non-idempotent file is excluded from the re-association analysis (its fixed @@ -441,7 +650,51 @@ impl ParenAuditCommand { // The floor UNDER the non-empty resolution: this audit's product is per-SITE, so a // corpus of files that hold no same-operator chain renders exactly the tables a // clean run does. The resolution's non-empty file list cannot see that. - check_graded_nonzero(report.sites, "logical re-association sites") + check_graded_nonzero(report.sites, "paren-authoring sites")?; + // A second floor, per CLASS — and an OPT-IN one, because it is a claim about the + // SEED SET rather than about the audit. Logical chains are everywhere, so the total + // above holds on any corpus; a relational `a < b > c` chain is written in the fixture + // tree and essentially nowhere else, so over real code zero relational sites is the + // correct reading. Only the invocation whose corpus holds the class asks for it. + if self.require_relational { + check_required_nonzero( + report.relational_sites(), + "relational chain sites", + "--require-relational", + )?; + } + Ok(()) + } + + /// Whether a site's twin is the SAME DOCUMENT to tsv's own parser — its precondition, + /// since a formatter cannot be asked to reach one fixed point from two programs. + /// + /// The relational splice is tree-preserving **in the language**: parenthesizing a whole + /// operand changes no program. It is **not** guaranteed to be tree-preserving under tsv's + /// `Parse`, so the twin may fail to parse there, or parse as a different tree. + /// + /// Checked only for the relational classes, and only because a paren around a `<` + /// operand genuinely can move tsv's PARSE: the type-argument lookahead's `(` head arm + /// grades bracket matching and the follow token alone, never the content, so a shell can + /// turn the comparison into a type-argument list. Where that list's body is no type, tsv + /// then REJECTS the twin — `x < (1 + 2) > (t, u)`, which acorn reads as the comparison + /// chain its paren-free twin is. Where the body happens to parse as one, the twin is a + /// DIFFERENT TREE — `p < (readonly.a) > (t, u)`, a call with type arguments to tsv and a + /// comparison chain to acorn. Either way it is a PARSER divergence against tsv's parse + /// oracle rather than a formatting question, so this audit excludes the site and counts + /// it, the way it does a comment-bound one. + /// + /// The logical class asks nothing of the kind: its splice re-associates a tree acorn + /// builds the same either way, so a twin that fails to parse there stays the loud + /// `VariantParseError` finding it always was. + fn twin_is_same_document(f: &str, site: &Site, base: &Value, parser: ParserType) -> bool { + let Some(mut twin) = tsv_parse_to_value(&splice(f, site), parser) else { + return false; + }; + let mut base = base.clone(); + strip_positions(&mut twin); + strip_positions(&mut base); + twin == base } fn scan_file(&self, path: &Path, report: &mut Report) { @@ -482,8 +735,19 @@ impl ParenAuditCommand { let map = Utf16ToByte::new(&f); let mut sites = Sites::default(); collect_sites(&wire, &f, &map, &mut sites); + sites.probed.retain(|site| { + if site.kind.is_relational() && !Self::twin_is_same_document(&f, site, &wire, parser) { + sites.parse_divergent += 1; + return false; + } + true + }); report.sites += sites.probed.len(); report.sites_comment_bound += sites.comment_bound; + report.sites_parse_divergent += sites.parse_divergent; + for site in &sites.probed { + *report.kind_sites.entry(site.kind).or_default() += 1; + } for site in &sites.probed { self.probe(path, &f, site, parser, report); } @@ -506,7 +770,7 @@ impl ParenAuditCommand { } }; *report.counts.entry(verdict).or_default() += 1; - *report.op_counts.entry((site.op, verdict)).or_default() += 1; + *report.kind_counts.entry((site.kind, verdict)).or_default() += 1; if verdict.is_finding() { if let Some(dir) = &self.dump_dir { report.dump_seq += 1; @@ -527,7 +791,7 @@ impl ParenAuditCommand { report.findings.push(Finding { path: path.display().to_string(), offset: site.open, - op: site.op, + kind: site.kind, verdict, context: line_context(f, site.open), first_diff, @@ -544,8 +808,8 @@ fn describe_first_diff(base: &str, variant: &str) -> Option<(usize, String, Stri }) } -fn print_human(report: &Report, examples: usize) { - println!("Paren-authoring independence audit (same-operator logical re-association)"); +fn print_human(report: &Report, examples: usize, require_relational: bool) { + println!("Paren-authoring independence audit (logical re-association + relational chain)"); println!( " files: {} scanned, {} parse-error, {} read-error, {} output-reparse-error, {} ignore-directive (skipped), {} base-non-idempotent", report.files_scanned, @@ -556,8 +820,10 @@ fn print_human(report: &Report, examples: usize) { report.base_non_idempotent.count(), ); println!( - " sites probed: {} ({} excluded — a `(` there would re-bind a forward-binding comment)", - report.sites, report.sites_comment_bound, + " sites probed: {} ({} excluded — a `(` there would re-bind a forward-binding comment; \ +{} relational excluded — tsv rejects the twin or parses it as a different program, a \ +parse-oracle question, not this gate's)", + report.sites, report.sites_comment_bound, report.sites_parse_divergent, ); println!(); println!(" verdicts:"); @@ -579,16 +845,16 @@ fn print_human(report: &Report, examples: usize) { ); println!(); - println!(" by operator (a zero row is a corpus gap, not a pass):"); - print!(" {:<10}", "operator"); + println!(" by site class (a zero row is a corpus gap, not a pass):"); + print!(" {:<14}", "class"); for v in Verdict::ALL { print!("{:>24}", v.key()); } println!(); - for op in LogicalOp::ALL { - print!(" {:<10}", op.label()); + for kind in SiteKind::ALL { + print!(" {:<14}", kind.label()); for v in Verdict::ALL { - print!("{:>24}", report.op_count(op, v)); + print!("{:>24}", report.kind_count(kind, v)); } println!(); } @@ -618,9 +884,14 @@ fn print_human(report: &Report, examples: usize) { // the run: a run that graded no site is about to fail the vacuity floor, and one // holding a base-non-idempotent file has already printed the ✗ list above and exits // 1. A ✓ over either reads as a pass the run is not entitled to. - if report.sites > 0 && !report.failed() { + // + // Every floor the run is HELD TO is read here, which is what `floors_met` states: a + // ✓ keyed on the total alone would print over a `--require-relational` run that then + // exits 1, and one that read the relational rows without the flag would withhold the + // ✓ from a real-code run that legitimately holds no relational chain and exits 0. + if report.floors_met(require_relational) && !report.failed() { println!(); - println!(" ✓ every same-operator chain formats identically to its parenthesized twin"); + println!(" ✓ every chain formats identically to its redundantly-parenthesized twin"); } return; } @@ -633,7 +904,7 @@ fn print_human(report: &Report, examples: usize) { " {}:{} {} [{}]", finding.path, finding.offset, - finding.op.label(), + finding.kind.label(), finding.verdict.key(), ); println!(" «{}»", finding.context); @@ -653,24 +924,24 @@ fn print_human(report: &Report, examples: usize) { } } -fn print_json(report: &Report) { +fn print_json(report: &Report, require_relational: bool) { let counts: serde_json::Map = Verdict::ALL .iter() .map(|v| (v.key().to_string(), serde_json::json!(report.count(*v)))) .collect(); - let op_counts: serde_json::Map = LogicalOp::ALL + let kind_counts: serde_json::Map = SiteKind::ALL .iter() - .map(|op| { + .map(|kind| { let per: serde_json::Map = Verdict::ALL .iter() .map(|v| { ( v.key().to_string(), - serde_json::json!(report.op_count(*op, *v)), + serde_json::json!(report.kind_count(*kind, *v)), ) }) .collect(); - (op.label().to_string(), Value::Object(per)) + (kind.label().to_string(), Value::Object(per)) }) .collect(); let findings: Vec = report @@ -680,7 +951,7 @@ fn print_json(report: &Report) { serde_json::json!({ "path": f.path, "offset": f.offset, - "operator": f.op.label(), + "class": f.kind.label(), "verdict": f.verdict.key(), "context": f.context, "first_diff": f.first_diff.as_ref().map(|(line, base, variant)| serde_json::json!({ @@ -701,8 +972,11 @@ fn print_json(report: &Report) { "files_panicked": report.panics.count(), "sites": report.sites, "sites_comment_bound": report.sites_comment_bound, + "sites_parse_divergent": report.sites_parse_divergent, "counts": counts, - "op_counts": op_counts, + "kind_counts": kind_counts, + "relational_sites": report.relational_sites(), + "require_relational": require_relational, "findings": findings, "base_non_idempotent_sample": report.base_non_idempotent.sample(), "panicked_sample": report.panics.sample(), @@ -727,6 +1001,25 @@ mod tests { assert!(report.failed()); } + /// The relational floor is a claim about the SEED SET, so it is read only by a run that + /// asked for it: a real-code corpus holds logical chains and no relational one, and + /// withholding the ✓ there reads as a failure the run does not have. + #[test] + fn the_relational_floor_is_read_only_when_required() { + let logical_only = Report { + sites: 2530, + ..Report::default() + }; + assert_eq!(logical_only.relational_sites(), 0); + assert!(logical_only.floors_met(false)); + assert!(!logical_only.floors_met(true)); + + // The total floor stays unconditional — a run that graded nothing meets neither. + let empty = Report::default(); + assert!(!empty.floors_met(false)); + assert!(!empty.floors_met(true)); + } + /// Enumerate the sites of a TypeScript snippet, as the audit does. fn sites_of(source: &str) -> Vec { let wire = tsv_parse_to_value(source, ParserType::TypeScript).expect("parses"); @@ -849,8 +1142,23 @@ mod tests { let map = Utf16ToByte::new(source); let mut out = Sites::default(); collect_sites(&wire, source, &map, &mut out); - let mut ops: Vec<&str> = out.probed.iter().map(|s| s.op.label()).collect(); + let mut ops: Vec<&str> = out.probed.iter().map(|s| s.kind.label()).collect(); ops.sort_unstable(); assert_eq!(ops, ["&&", "??", "||"]); } + + /// A relational `<`…`>` chain contributes BOTH shells — around the chain and around the + /// `<` operand — and a `<` under any other operator contributes neither, since the rule + /// the class grades is keyed on that one join. + #[test] + fn a_relational_chain_enumerates_both_shells() { + let mut kinds: Vec<&str> = sites_of("const x = (a < b) > c;") + .iter() + .map(|s| s.kind.label()) + .collect(); + kinds.sort_unstable(); + assert_eq!(kinds, ["< > chain", "< > operand"]); + assert!(sites_of("const x = a < b;").is_empty()); + assert!(sites_of("const x = a > b > c;").is_empty()); + } } diff --git a/crates/tsv_svelte_compile/src/build.rs b/crates/tsv_svelte_compile/src/build.rs index 82a1f50ec..e3ae04919 100644 --- a/crates/tsv_svelte_compile/src/build.rs +++ b/crates/tsv_svelte_compile/src/build.rs @@ -441,6 +441,9 @@ impl<'arena> Builder<'arena> { operator: op, right, span, + // Minted code, not source the printer will re-lex: the builder emits its own + // spelling, and no shape it mints opens a type-argument region. + relexes_as_type_arguments: false, }) } diff --git a/crates/tsv_svelte_compile/src/erase.rs b/crates/tsv_svelte_compile/src/erase.rs index df5fde85b..8bae2f484 100644 --- a/crates/tsv_svelte_compile/src/erase.rs +++ b/crates/tsv_svelte_compile/src/erase.rs @@ -1714,6 +1714,10 @@ impl<'arena> Eraser<'arena, '_> { tsv_ts::ast::internal::BinaryExpression { left: left.unwrap_or(binary.left), right: right.unwrap_or(binary.right), + // `relexes_as_type_arguments` rides along: it is a claim about the SOURCE + // bytes this rewrite invalidates, and inheriting is the SAFE direction — a + // stale `true` costs a redundant paren pair, a stale `false` an output + // nothing reparses. ..binary.clone() }, )) diff --git a/crates/tsv_svelte_compile/src/store_rewrite.rs b/crates/tsv_svelte_compile/src/store_rewrite.rs index dad06a9d9..bb42af88e 100644 --- a/crates/tsv_svelte_compile/src/store_rewrite.rs +++ b/crates/tsv_svelte_compile/src/store_rewrite.rs @@ -877,6 +877,10 @@ impl<'arena> StoreRewriter<'_, 'arena> { Some(Expression::BinaryExpression(ast::BinaryExpression { left: left.unwrap_or(binary.left), right: right.unwrap_or(binary.right), + // `relexes_as_type_arguments` rides along: it is a claim about the SOURCE + // bytes this rewrite invalidates, and inheriting is the SAFE direction — a + // stale `true` costs a redundant paren pair, a stale `false` an output + // nothing reparses. ..binary.clone() })) } diff --git a/crates/tsv_svelte_compile/src/template_value.rs b/crates/tsv_svelte_compile/src/template_value.rs index a7fa9ea51..0ebcef7d6 100644 --- a/crates/tsv_svelte_compile/src/template_value.rs +++ b/crates/tsv_svelte_compile/src/template_value.rs @@ -289,6 +289,10 @@ fn rebuild_value<'arena>( Expression::BinaryExpression(BinaryExpression { left, right, + // `relexes_as_type_arguments` rides along: it is a claim about the SOURCE + // bytes this rewrite invalidates, and inheriting is the SAFE direction — a + // stale `true` costs a redundant paren pair, a stale `false` an output + // nothing reparses. ..b.clone() }) } diff --git a/crates/tsv_ts/src/ast/internal/expressions.rs b/crates/tsv_ts/src/ast/internal/expressions.rs index ef95526b6..2dfb37a7b 100644 --- a/crates/tsv_ts/src/ast/internal/expressions.rs +++ b/crates/tsv_ts/src/ast/internal/expressions.rs @@ -578,6 +578,30 @@ pub struct BinaryExpression<'arena> { pub operator: BinaryOperator, pub right: &'arena Expression<'arena>, pub span: Span, + /// For a `<` node UNDER A `>` only: whether the region this `<` opens would re-lex as a + /// TYPE-ARGUMENT LIST once printed — the parser's own relaxed reading of the same + /// lookahead that decided this `<` is the less-than operator, recorded here because the + /// printer cannot re-derive it (it holds a tree, and the question is about bytes). + /// + /// The two readings grade different TEXT — the printed form against every parser that + /// reads tsv's output, rather than the source against acorn. The printer's own line + /// breaks are the plainest case: it folds the author's break away (`fn(t, u)` + /// prints as `fn < A[T] > (t, u)`, a `CallExpression` on re-parse) and may add its own + /// past the `>` (`x < y >⏎{ a: 1 }` is an instantiation plus a free-standing block). + /// Every place the two readings differ, with the seam each is read at, is enumerated + /// once on `TypeArgScan`. + /// + /// A `>` whose LEFT operand is such a `<` therefore keeps a paren pair — + /// `(fn < A[T]) > (t, u)` — synthesized and retained by `needs_parens`, which is the one + /// reader of this field. + /// + /// Set LAZILY, at the `>` that would close the region rather than at the `<`: the + /// verdict is a fact about the join of the two tokens, and a `<` with no `>` over it — + /// every ordinary comparison — must not pay the scan. The node is already in the arena + /// by then, so the parser re-allocates this one node to set the bit. + /// + /// `false` on every other operator, and free in the struct's existing padding. + pub relexes_as_type_arguments: bool, } impl<'arena> BinaryExpression<'arena> { diff --git a/crates/tsv_ts/src/parser/expression.rs b/crates/tsv_ts/src/parser/expression.rs index c30bfffd3..a35679de9 100644 --- a/crates/tsv_ts/src/parser/expression.rs +++ b/crates/tsv_ts/src/parser/expression.rs @@ -18,6 +18,7 @@ use tsv_lang::{ParseError, Span, TAB_WIDTH}; use super::Parser; use super::expression_lookahead::{ArrowHead, matching_angle_close}; +use super::expression_type_args::TypeArgScan; use super::scan::{ LeadingZeroLiteral, classify_leading_zero, parse_number_literal, skip_whitespace_and_comments, }; @@ -267,6 +268,23 @@ fn contains_type_or_satisfies_tag(value: &str) -> bool { false } +/// The byte offset of the infix operator that joins an ALREADY-BUILT binary node's two +/// operands, located forward from the left operand's `span.end` — the first significant +/// byte past it that is not a `)`, since a paren shell around an operand is outside that +/// operand's own span (`(a) < b`, `((a)) < b`). `None` when the byte found is not +/// `expected`, which is the whole verification: a caller that cannot place its own +/// operator asks nothing further of it. +/// +/// A binary node records no operator offset of its own — 4 bytes on every one, to serve +/// the one reader below — so the bytes answer instead, and the reader is a cold path. +fn infix_operator_offset(bytes: &[u8], left_end: usize, expected: u8) -> Option { + let mut pos = skip_whitespace_and_comments(bytes, left_end); + while bytes.get(pos) == Some(&b')') { + pos = skip_whitespace_and_comments(bytes, pos + 1); + } + (bytes.get(pos) == Some(&expected)).then_some(pos) +} + /// Infix operator info: binding powers and the corresponding binary operator. /// /// Returns `(left_bp, right_bp, operator)` if the token is a binary operator. @@ -622,6 +640,36 @@ impl<'a, 'arena> Parser<'a, 'arena> { )); } + // Ask the RELAXED reading of the same type-argument lookahead that declined + // the `<` below — the one component that has already read these bytes, and the + // last moment they are still in reach (the printer holds a tree). It answers + // whether this chain's PRINTED form re-lexes as a type-argument list, which is + // what decides a paren pair at the enclosing `>` + // (`Printer::needs_parens_binary_operand`). + // + // Asked HERE, at the `>` that would close the region, rather than at the `<` + // that opens it: the verdict is a fact about the JOIN of the two tokens, and + // this is the first point both exist. A `<` with no `>` over it — `check(a < b)` + // and every other ordinary comparison — then pays nothing, where a question asked + // at the `<` would walk each one to the statement's end looking for a close that + // is not there. The bit rides the `<` node, already in the arena, so setting it + // re-allocates that one node; only a chain that takes the pair pays for it. + if operator == BinaryOperator::GreaterThan + && let Expression::BinaryExpression(child) = left.expr + && child.operator == BinaryOperator::LessThan + && let Some(lt) = infix_operator_offset( + self.source.as_bytes(), + self.local_pos(child.left.span().end), + b'<', + ) + && self.is_type_arguments_start_at(lt, TypeArgScan::Relex) + { + left.expr = arena.alloc(Expression::BinaryExpression(BinaryExpression { + relexes_as_type_arguments: true, + ..child.clone() + })); + } + self.advance()?; // consume operator // Parse right-hand side with right binding power @@ -637,6 +685,8 @@ impl<'a, 'arena> Parser<'a, 'arena> { operator, right: right.expr, span, + // Set only by the lazy `>` reading above, which re-allocates the node. + relexes_as_type_arguments: false, })), actual_start: expr_start as u32, actual_end: right.actual_end, @@ -1085,7 +1135,7 @@ impl<'a, 'arena> Parser<'a, 'arena> { let type_arguments = if matches!( self.current_kind(), TokenKind::LessThan | TokenKind::LeftShift - ) && self.is_type_arguments_start() + ) && self.is_type_arguments_start(TypeArgScan::Parse) { Some(self.parse_type_parameter_instantiation()?) } else { @@ -1305,7 +1355,7 @@ impl<'a, 'arena> Parser<'a, 'arena> { ); } TokenKind::LessThan | TokenKind::LeftShift - if self.is_type_arguments_start() => + if self.is_type_arguments_start(TypeArgScan::Parse) => { // obj?.(args) - optional call with explicit type arguments; // only a call may follow (`a?.` without `(` is a syntax error) @@ -1452,7 +1502,7 @@ impl<'a, 'arena> Parser<'a, 'arena> { // leave it for the caller; only `Base(...)` is consumed here (the // `(` arm below flattens the instantiation into a call with type // arguments). A `<` that isn't type args stops the chain either way. - let consume = self.is_type_arguments_start() + let consume = self.is_type_arguments_start(TypeArgScan::Parse) && (mode == SubscriptMode::Normal || self.is_type_args_followed_by_call()); if consume { left = self.parse_instantiation_expression(left)?; @@ -1563,7 +1613,7 @@ impl<'a, 'arena> Parser<'a, 'arena> { return false; } - match matching_angle_close(bytes, start + 1) { + match matching_angle_close(bytes, start + 1, TypeArgScan::Parse) { None => false, Some(close) => { let after = skip_whitespace_and_comments(bytes, close + 1); @@ -2124,8 +2174,8 @@ impl<'a, 'arena> Parser<'a, 'arena> { /// Parse a TypeScript instantiation expression `expr` from an /// already-parsed `left` operand. /// - /// The caller gates this on `is_type_arguments_start()`: when `<` follows an - /// expression it could be type arguments (`f`, `arr`) or a + /// The caller gates this on `is_type_arguments_start(TypeArgScan::Parse)`: when `<` + /// follows an expression it could be type arguments (`f`, `arr`) or a /// comparison (`a < b`), and that lookahead disambiguates before we commit. fn parse_instantiation_expression( &mut self, @@ -2637,7 +2687,9 @@ impl<'a, 'arena> Parser<'a, 'arena> { // disambiguates: it consumes them into the tag and the callee chain // continues (`new Foo`x`.bar`); otherwise they are the `new`'s and // the chain ends here. - _ if self.check_less_than_in_type() && self.is_type_arguments_start() => { + _ if self.check_less_than_in_type() + && self.is_type_arguments_start(TypeArgScan::Parse) => + { let ta = self.parse_type_parameter_instantiation()?; if matches!( self.current_kind(), diff --git a/crates/tsv_ts/src/parser/expression_lookahead.rs b/crates/tsv_ts/src/parser/expression_lookahead.rs index 3cba9f958..93ba6a1e8 100644 --- a/crates/tsv_ts/src/parser/expression_lookahead.rs +++ b/crates/tsv_ts/src/parser/expression_lookahead.rs @@ -8,6 +8,7 @@ // // All functions operate on byte slices for performance (no tokenization needed). +use super::expression_type_args::TypeArgScan; use super::scan::{ identifier_starts_at, is_word_at, skip_identifier, skip_numeric_literal, skip_whitespace_and_comments, @@ -451,7 +452,7 @@ fn scan_for_arrow(bytes: &[u8], colon: usize) -> bool { position = TypePos::Atom; } b'<' => { - let Some(close) = matching_angle_close(bytes, pos + 1) else { + let Some(close) = matching_angle_close(bytes, pos + 1, TypeArgScan::Parse) else { return false; }; // At a full-type position `<…>` opens a generic function type, @@ -724,8 +725,18 @@ pub(super) fn is_function_type_start(bytes: &[u8], pos: usize) -> bool { /// `)`, `]`, `}`, or `;` at depth 0, and the close isn't followed by a token /// that makes the `>` a comparison instead: a `>`/`>>`/`>>>` (relational or /// shift) run, or an expression-starting token on the same line. -pub(super) fn scan_for_closing_angle_bracket(bytes: &[u8], pos: usize) -> bool { - match matching_angle_close(bytes, pos) { +/// +/// The follower half is the one the two readings disagree on. [`TypeArgScan::Relex`] asks +/// about the REGION alone and stops at the matching `>`: past a line terminator the +/// [`TypeArgScan::Parse`] arm below commits the list ahead of any expression, and whether the +/// printer puts a break there is unknowable where the question is asked. (Which followers +/// commit, for tsc and for acorn-typescript, is stated in `docs/conformance_prettier_ts.md` +/// §Relational chain type-argument parens; where tsc refuses one this parse commits on, +/// [`TypeArgScan`]'s soundness property is why the pair still stands.) The `>`-led run is +/// NOT part of that half — a `>>` / `>>>` is one token the printer can never split, so both +/// readings reject it. +pub(super) fn scan_for_closing_angle_bracket(bytes: &[u8], pos: usize, scan: TypeArgScan) -> bool { + match matching_angle_close(bytes, pos, scan) { None => false, Some(close) => { let after = skip_whitespace_and_comments(bytes, close + 1); @@ -751,8 +762,13 @@ pub(super) fn scan_for_closing_angle_bracket(bytes: &[u8], pos: usize) -> bool { // `tokenCanStartExpression && !hasPrecedingLineBreak` bail). `(` (call), // a template (tagged template), and other non-expression tokens (`;`, // `,`, `)`, `.`, an operator…) continue the instantiation — and across a - // line break an expression-starting token begins a new statement via ASI, - // leaving the `<…>` an instantiation. + // line break an expression-starting token leaves the `<…>` an instantiation + // too, whether it then begins a new statement via ASI (`x⏎c`) or continues + // as an operand (`x⏎+1`). The whole follower split, tsc's beside acorn's, is + // in `docs/conformance_prettier_ts.md` §Relational chain type-argument parens. + if !scan.reads_source_as_written() { + return true; + } !starts_expression_after_type_args(bytes, after) || has_line_terminator_between(bytes, close + 1, after) } @@ -769,7 +785,7 @@ pub(super) fn scan_for_closing_angle_bracket(bytes: &[u8], pos: usize) -> bool { /// parenthesized (`a << b > (c)`): an arrow can never be a relational /// operand, so real shift code never has `(…) =>` after the would-be close. pub(super) fn is_generic_function_type_start(bytes: &[u8], pos: usize) -> bool { - let Some(close) = matching_angle_close(bytes, pos) else { + let Some(close) = matching_angle_close(bytes, pos, TypeArgScan::Parse) else { return false; }; let after = skip_whitespace_and_comments(bytes, close + 1); @@ -822,9 +838,30 @@ pub(super) fn is_construct_type_start(bytes: &[u8], pos: usize) -> bool { /// (`pos` is the first byte after the `<`), or `None` if an unbalanced `)`, /// `]`, `}`, or a top-level `;` intervenes. /// +// TODO: this walk is O(distance to the enclosing delimiter) and every `<` in a construct +// pays it, so a call whose arguments are all comparisons is quadratic in the argument count +// — `f(a1 < b1, …, aN < bN)` quadruples per doubling of N, against a `+` control that stays +// flat and unmeasurable. (A wall-clock figure is deliberately not quoted: the ratio is the +// property, and an absolute second belongs to one machine.) Both readings pay it — a `<` that +// opens no type-argument list reads to the construct's own close before it can say so. A memo keyed on the enclosing delimiter's span would collapse it; nothing +// real has the shape, so it has not been worth the state. +/// /// Operator disambiguation: `<=` and `>=` are comparison operators (not angle /// brackets) and `=>` is an arrow operator (not a closing bracket). -pub(super) fn matching_angle_close(bytes: &[u8], mut pos: usize) -> Option { +/// +/// The unbalanced `)` is the one stop the two readings split on. Under +/// [`TypeArgScan::Relex`] a `)` the region did not open is a **paren shell the printer +/// strips**, and the question is about the PRINTED bytes, where it is absent — so it does +/// not end the region and the scan reads on. Without that, the pair this reading exists to +/// justify would erase itself on the next pass: `(a < b) > c` re-read as source stops the +/// scan at its own `)` and prints back out as `a < b > c`. `]`, `}` and a top-level `;` +/// stop both readings — a bracket or brace is never a shell the printer strips, and a `;` +/// ends the statement in either spelling. +pub(super) fn matching_angle_close( + bytes: &[u8], + mut pos: usize, + scan: TypeArgScan, +) -> Option { let mut angle_depth: i32 = 1; let mut paren_depth: i32 = 0; let mut bracket_depth: i32 = 0; @@ -864,7 +901,12 @@ pub(super) fn matching_angle_close(bytes: &[u8], mut pos: usize) -> Option { paren_depth -= 1; if paren_depth < 0 { - return None; // Unbalanced - hit call/group end + if scan.reads_source_as_written() { + return None; // Unbalanced - hit call/group end + } + // A shell the printer strips is not in the form this reading grades; + // re-level and read on (see the doc above). + paren_depth = 0; } } b'[' => bracket_depth += 1, diff --git a/crates/tsv_ts/src/parser/expression_type_args.rs b/crates/tsv_ts/src/parser/expression_type_args.rs index fef791dc6..0223acf13 100644 --- a/crates/tsv_ts/src/parser/expression_type_args.rs +++ b/crates/tsv_ts/src/parser/expression_type_args.rs @@ -12,6 +12,120 @@ use super::scan::{ }; use tsv_lang::source_scan::{TriviaProfile, skip_template_literal, skip_trivia}; +/// Which reading of the type-argument lookahead a caller wants — the one parameter the two +/// readings are threaded through, so the walk stays a single body and they cannot drift. +/// +/// Both readings ask the same structural question. They differ in WHICH TEXT they ask it of +/// and WHOSE grammar answers: [`Parse`] grades the source bytes as the author wrote them +/// against acorn-typescript, tsv's AST drop-in oracle; [`Relex`] grades the form the printer +/// would emit from them against every parser that will read tsv's output — tsc, and tsv's +/// own [`Parse`]. +/// +/// **Four tokens the printer MOVES**, each a place the printed form is not the source: +/// +/// - **a line break before a `[`, which the printer folds away.** A break there ends the type +/// to tsc and acorn-typescript alike (the loop in each is named in +/// `docs/conformance_prettier_ts.md` §Relational chain type-argument parens), so +/// `fn(t, u)` is a comparison chain — and every parse-then-format entry point +/// folds that break (`tsv_lang::printing::normalize_carriage_returns`, plus the printer's +/// own soft-line joins) before the output is read back. [`type_operand_follow_commits`]'s +/// `[` arm, and [`continues_as_type`]'s index-chain twin. +/// - **trivia between a numeric type's SIGN and its digits, likewise folded.** `fn<-⏎⏎1>(t)` +/// is a comparison chain whose printed form is `fn < -1 > t`, one literal type in the +/// region ([`skip_signed_numeric_literal`]). +/// - **a paren shell, which the printer strips**, read at both ends of the region. Past an +/// operand, a `)` the region did not open is not in the printed form, so it neither ends +/// the operand nor ends the scan ([`skip_relex_operand_suffixes`], and +/// [`matching_angle_close`](super::expression_lookahead::matching_angle_close) mid-scan) — +/// without which the pair this reading justifies would erase itself on the next pass, +/// since tsv's own output is the shell-bearing spelling (`(a < b) > c`). At the HEAD, the +/// shell is looked THROUGH and the head question asked of its content +/// ([`type_arg_head_commits`]'s `(` arm), so `a < (arr[b - 1]) > c` grades the arithmetic +/// its own paren-free twin does. +/// - **a line break past the `>`, which the printer may or may not add.** Past one, tsv's +/// own [`Parse`] (with acorn-typescript) commits the list ahead of any expression. Which +/// followers commit, for tsc and for acorn-typescript, is stated once in the same catalog +/// entry; where tsc refuses a follower that [`Parse`] commits on, the pair is owed to +/// soundness (below), not to tsc. Whether the printer takes the break is unknowable where +/// parens are decided, so [`Relex`] asks about the REGION alone and skips the follower +/// entirely ([`scan_for_closing_angle_bracket`]). +/// +/// **One token the two ORACLES read differently**, no printer move involved: the non-null +/// `!`. `T!` is tsc's `JSDocNonNullableType` — prefix and postfix — so `` is a +/// type-argument list to the compiler, where acorn-typescript reads a comparison and tsv's +/// parse follows it. Admitting it at [`Parse`] would move tsv's AST off the drop-in +/// contract; refusing it at [`Relex`] would emit an output tsc reads as a different program +/// ([`skip_relex_operand_suffixes`] for the postfix, [`type_arg_head_commits`]'s `!` arm for +/// the prefix). +/// +/// **Two properties bound every relaxation above, and neither is "[`Relex`] is never +/// stricter than [`Parse`] on one string".** That comparison grades both readings against +/// the SAME bytes, which is a proxy — it holds only where the source and the printed form +/// give [`Parse`] the same answer at that `<`, and the whole reason [`Relex`] exists is the +/// places they do not (a line break, a shell). The two properties name the texts apart: +/// +/// - **Soundness.** For every document `D`: if tsv's own [`Parse`] reads a type-argument +/// region at the `<` of `format(D)`, the printer must have put a pair there. tsv's parser +/// is one of the readers of the output the verdict is about, so a `<` [`Relex`] leaves +/// bare and [`Parse`] then claims is an output tsv cannot reparse. **Nothing gates this +/// today**: `gaps:audit` grades the fixture tree as authored plus its injections, and no +/// fixture can hold the shapes that break it — a fixture input must format to itself, and +/// the broken form is one only the printer produces. +/// - **Independence.** [`Relex`] must agree with ITSELF across the redundant-paren +/// spellings of one program: `a < X > c` and `a < (X) > c` are one document, so they owe +/// one verdict. Gated by `deno task paren:audit` (its `< > chain` and `< > operand` +/// classes). This is soundness's dual: a `(` arm that graded nothing would give a +/// parenthesized operand a pair its bare twin lacks. +/// +/// The bracketed heads are where soundness bites first: neither grades its body, so a `>` +/// with a line terminator past it — or a `(` or a template on the same line — commits them on +/// any content, and tsv reads `x < { ...s } >⏎c` and `x < { ...s } > (c, d)` as type-argument +/// lists and then rejects both — where acorn and tsc both read the comparison chain. Grading the body under [`Relex`] alone (a tuple and a type +/// literal are types, an array of update expressions and an object spread are not) would +/// therefore print a bare chain tsv itself cannot reparse. The pair stands on every +/// bracketed head instead; the underlying over-rejection is [`Parse`]'s, and belongs to the +/// parse oracles. +/// +/// **The `(` arm's look-through carries soundness only where the printer STRIPS the shell.** +/// Where it does, the content IS the printed bytes and the two readings are asking about one +/// text. Where the printer **keeps** the shell, they are not: [`Relex`] answers about the +/// content while [`Parse`] answers about the `(`-headed region that is actually printed, and +/// on any content that is no type they disagree — [`Relex`] declines the pair and `format` +/// emits a document [`Parse`] then claims as a type-argument list. Two triggers reach it, the +/// same two the bracketed heads have: a follower that commits the head with no break at all +/// (`x < (a = b) > (c, d)`, or a template or arrow-in-parens follower, is unreparseable on one +/// line), and a width at which the `>` ends a line (`x < (a = b) > c` is harmless only while +/// it fits). The class is every operand whose shell survives printing and whose head and +/// follow token are no type — assignment and compound assignment, a conditional, `||` / +/// `&&` / `??`, equality, `^`, `in` / `instanceof`, `await`, `yield`, `as` / `satisfies`. A +/// kept shell whose content happens to SPELL a type is not in it: a sequence spells the +/// argument separator, `&` and `|` a type intersection or union, and `() =>` a function +/// type, so [`Relex`] commits and the pair stands. The residual is the same [`Parse`]-side +/// head over-rejection as the bracketed ones, and it is the parse oracles' subject. +/// +/// [`Parse`]: TypeArgScan::Parse +/// [`Relex`]: TypeArgScan::Relex +#[derive(Clone, Copy, PartialEq, Eq)] +pub(super) enum TypeArgScan { + /// What the PARSER commits to: the input's own bytes, line terminators and parens and + /// all. + Parse, + /// What the PRINTED form would re-lex as, which is the printer's question. Never decides + /// a parse; it only records whether a paren pair has to stand between two tokens (see + /// `Printer::needs_parens_binary_operand`). + Relex, +} + +impl TypeArgScan { + /// Whether this reading grades the source bytes AS WRITTEN, against acorn. False for + /// [`Relex`](TypeArgScan::Relex), which grades the printed form — whose readers are + /// named on [`TypeArgScan`], along with the sites that read each difference. + #[inline] + pub(super) const fn reads_source_as_written(self) -> bool { + matches!(self, TypeArgScan::Parse) + } +} + impl<'a, 'arena> Parser<'a, 'arena> { /// Check if current position starts type arguments: `` /// @@ -29,131 +143,187 @@ impl<'a, 'arena> Parser<'a, 'arena> { /// /// Every operand-headed arm ends at the shared follow-token filter /// [`type_operand_follow_commits`], which is what decides call vs comparison. - pub(super) fn is_type_arguments_start(&self) -> bool { + /// + /// `scan` names which of the two readings the caller wants — see [`TypeArgScan`]. The + /// parser always asks [`TypeArgScan::Parse`]; the one [`TypeArgScan::Relex`] asker is a + /// `>` reducing over a `<` left operand, recording on that `<` node whether its PRINTED + /// form would re-lex as a type-argument list. + pub(super) fn is_type_arguments_start(&self, scan: TypeArgScan) -> bool { + self.is_type_arguments_start_at(self.current.start as usize, scan) + } + + /// [`Parser::is_type_arguments_start`] asked at an EXPLICIT `<`, rather than at the + /// token the parser is sitting on. + /// + /// The relaxed [`TypeArgScan::Relex`] reading is taken at a `>` — the point at which + /// both tokens of the join it grades exist — by which time the lexer has long left the + /// `<` behind, so that caller supplies the offset itself. + pub(super) fn is_type_arguments_start_at(&self, lt_start: usize, scan: TypeArgScan) -> bool { let bytes = self.source.as_bytes(); - let start = self.current.start as usize; // Must start with '<' - if start >= bytes.len() || bytes[start] != b'<' { + if lt_start >= bytes.len() || bytes[lt_start] != b'<' { return false; } // Skip whitespace AND comments after '<' - comments can appear before types - let pos = skip_whitespace_and_comments(bytes, start + 1); - if pos >= bytes.len() { - return false; + let pos = skip_whitespace_and_comments(bytes, lt_start + 1); + pos < bytes.len() && type_arg_head_commits(bytes, pos, scan) + } +} + +/// Whether the type-argument HEAD at `pos` — the first significant byte past a `<` — +/// opens a type-argument list, dispatching on that byte. Split out of +/// [`Parser::is_type_arguments_start`] because the `(` arm re-enters it: under +/// [`TypeArgScan::Relex`] a paren shell the printer strips is not in the graded form, so +/// the head question is asked again of its CONTENT. +fn type_arg_head_commits(bytes: &[u8], pos: usize, scan: TypeArgScan) -> bool { + // Type keywords come ahead of the byte dispatch — every one is also + // identifier-shaped, so the identifier arm below would otherwise claim them. + match type_keyword_at(bytes, pos) { + // An atom-shaped keyword (`string`, `null`, `this`, …) is as much a value + // name as a type head, so it takes the identifier arm's follow-token + // filter: only content that could continue a TYPE past the head commits. + // That is what keeps ``p < string ? q : r > `t` `` a comparison (matching + // acorn) while `f()`, `f()` and `p(t, u)` + // stay instantiations — the atom answers every follow-token question + // exactly as an ordinary identifier does. + Some(TypeKeywordKind::Atom) => { + return check_identifier_type_arg_pattern(bytes, pos, scan); } - // Type keywords come ahead of the byte dispatch — every one is also - // identifier-shaped, so the identifier arm below would otherwise claim them. - match type_keyword_at(bytes, pos) { - // An atom-shaped keyword (`string`, `null`, `this`, …) is as much a value - // name as a type head, so it takes the identifier arm's follow-token - // filter: only content that could continue a TYPE past the head commits. - // That is what keeps ``p < string ? q : r > `t` `` a comparison (matching - // acorn) while `f()`, `f()` and `p(t, u)` - // stay instantiations — the atom answers every follow-token question - // exactly as an ordinary identifier does. - Some(TypeKeywordKind::Atom) => { - return check_identifier_type_arg_pattern(bytes, pos); + // `this` is an atom too, minus one rule: `this.` is member access, never a + // type (allow `this /* comment */ .`). `this` cannot head a qualified type + // name — unlike `string`, an ordinary identifier token to the type grammar — + // so the filter's qualified-name walk must not see the `.`. + Some(TypeKeywordKind::This) => { + let after_this = skip_whitespace_and_comments(bytes, pos + b"this".len()); + if bytes.get(after_this) == Some(&b'.') { + return false; } + return check_identifier_type_arg_pattern(bytes, pos, scan); + } - // `this` is an atom too, minus one rule: `this.` is member access, never a - // type (allow `this /* comment */ .`). `this` cannot head a qualified type - // name — unlike `string`, an ordinary identifier token to the type grammar — - // so the filter's qualified-name walk must not see the `.`. - Some(TypeKeywordKind::This) => { - let after_this = skip_whitespace_and_comments(bytes, pos + b"this".len()); - if bytes.get(after_this) == Some(&b'.') { - return false; - } - return check_identifier_type_arg_pattern(bytes, pos); - } + // A type-operator keyword is keyword-then-operand: the follow token is its + // operand, so the follow-token filter's `_ => false` default would reject + // `f()` and `f()`. Each operator asks its own + // operand-shape question instead — see `type_operator_commits`. + Some(TypeKeywordKind::Operator(op)) => { + return type_operator_commits(bytes, op, pos, scan); + } - // A type-operator keyword is keyword-then-operand: the follow token is its - // operand, so the follow-token filter's `_ => false` default would reject - // `f()` and `f()`. Each operator asks its own - // operand-shape question instead — see `type_operator_commits`. - Some(TypeKeywordKind::Operator(op)) => { - return type_operator_commits(bytes, op, pos); - } + None => {} + } - None => {} + // Dispatch based on first token after '<' + match bytes[pos] { + // Identifier: type reference like `` or `` + _ if identifier_starts_at(bytes, pos) => { + check_identifier_type_arg_pattern(bytes, pos, scan) } - // Dispatch based on first token after '<' - match bytes[pos] { - // Identifier: type reference like `` or `` - _ if identifier_starts_at(bytes, pos) => check_identifier_type_arg_pattern(bytes, pos), - - // A type argument starting with `(`: a function type (`<(x: T) => R>`, - // `<() => R>`) or a parenthesized type (`<(A | B) & C>`, - // `<(() => void) | null>`). `is_function_type_start` fast-paths the arrow - // shapes; otherwise skip the balanced group and ask the shared follow-token - // filter (as the `{`/`[`/literal arms do), so `x < (b)`, `x < (b) > c` and - // `x < (a) ? q : r > (t, u)` stay comparisons while `callee<(T)>(…)` and - // `x < (b) > (c)` are type arguments — matching acorn's - // `canFollowTypeArgumentsInExpression`. - b'(' => { - is_function_type_start(bytes, pos) - || matching_delimiter_close(bytes, pos) - .is_some_and(|close| type_operand_follow_commits(bytes, close + 1)) - } - - // A second `<` — the tail of a `<<` shift token, or a spaced - // `< <` — can only open a generic function type - // (`f<(v: T) => void>()`); shift chains (`a << b > c`) never - // match its `>`-then-`(` shape. - b'<' => is_generic_function_type_start(bytes, pos + 1), - - // Object/tuple literal types — but `{`/`[` equally start object and array - // *value* literals, so `x < {a: 1}` is a comparison. Skip the balanced - // group, then only a type-continuing follow token commits: `f<{ a: T }>()` - // and `f<[T, U] | null>()` are type arguments, `x < [1] ? q : r > (t, u)` - // is a comparison whatever sits past the would-be closing `>`. - b'{' | b'[' => matching_delimiter_close(bytes, pos) - .is_some_and(|close| type_operand_follow_commits(bytes, close + 1)), - - // String literal types — the same follow-token question after the literal: - // `f<'a' | 'b'>()` commits, `x < 'a' + 'b' > (t, u)` stays a comparison. - b'\'' | b'"' => skip_trivia(bytes, pos, bytes.len(), TriviaProfile::JS) - .is_some_and(|after| type_operand_follow_commits(bytes, after)), - - // Template literal types — skipped interpolation-aware (the opaque - // quote-to-quote trivia scan would mis-pair backticks across a nested - // `` `${`x`}` ``), then the same follow-token question. - b'`' => { - let after = skip_template_literal(bytes, pos, bytes.len()); - type_operand_follow_commits(bytes, after) + // A type argument starting with `(`: a function type (`<(x: T) => R>`, + // `<() => R>`) or a parenthesized type (`<(A | B) & C>`, + // `<(() => void) | null>`). `is_function_type_start` fast-paths the arrow + // shapes; otherwise skip the balanced group and ask the shared follow-token + // filter (as the `{`/`[`/literal arms do), so `x < (b)`, `x < (b) > c` and + // `x < (a) ? q : r > (t, u)` stay comparisons while `callee<(T)>(…)` and + // `x < (b) > (c)` are type arguments — matching acorn-typescript's follower handling + // (quoted in `docs/conformance_prettier_ts.md` §Relational chain type-argument parens). + // + // Past the arrow fast path, [`TypeArgScan::Relex`] LOOKS THROUGH the shell instead + // of skipping it: a redundant pair is not in the form that reading grades + // (`a < (arr[b - 1]) > c` prints as `a < arr[b - 1] > c`), so the head question is + // the CONTENT's, asked with the content's own first byte. Skipping to the follow + // filter would grade nothing at all there — the filter is the region's only + // discriminator and [`TypeArgScan::Relex`] deletes its follow-token half, so every + // parenthesized operand would commit, type or not. The closing side needs no rule + // of its own: [`skip_relex_operand_suffixes`] already steps over the `)`. + b'(' => { + if is_function_type_start(bytes, pos) { + true + } else if scan.reads_source_as_written() { + matching_delimiter_close(bytes, pos) + .is_some_and(|close| type_operand_follow_commits(bytes, close + 1, scan)) + } else { + type_arg_head_commits(bytes, skip_whitespace_and_comments(bytes, pos + 1), scan) } + } - // Numeric literal types: `<42>`, `<-1>`, `<.5>` — but `x < 42` is a - // comparison, so the literal alone decides nothing. Skip it (sign and a - // missing integer part included: `DecimalLiteral :: . DecimalDigits` is a - // literal type like any other, so `f<.5>()` is an instantiation to acorn; - // `-b` skips nothing and is a unary negation, never a type), then only a - // type-continuing follow token commits: `f<-1>()`, `f<.5>()` and - // `f<0 | 1>()` are type arguments, `x < 1 + 2 > (t, u)` and - // ``x < .5 ? q : r > `t` `` stay comparisons. - // - // The head class is [`numeric_literal_starts_at`], shared with the index and - // operand sites so a literal cannot be admitted at one and refused at another. - _ if numeric_literal_starts_at(bytes, pos) => { - let after = skip_numeric_literal(bytes, pos); - after > pos && type_operand_follow_commits(bytes, after) - } + // A non-null `!` ahead of the operand — `` is tsc's JSDoc non-nullable type, + // so `a < !b >⏎c` is an instantiation plus a statement where the flat line is a + // comparison chain. Only [`TypeArgScan::Relex`] reads it: acorn-typescript, tsv's + // parse oracle, has no such type, so admitting it at [`TypeArgScan::Parse`] would + // move a PARSE off the drop-in contract. `!=` / `!==` are operators, never a mark. + b'!' if !scan.reads_source_as_written() && bytes.get(pos + 1) != Some(&b'=') => { + type_arg_head_commits(bytes, skip_whitespace_and_comments(bytes, pos + 1), scan) + } - // A leading `|`/`&` on the first union/intersection member - // (`f<| A | B>()`, `f<& A & B>()`) — the form prettier itself emits - // whenever such a type argument breaks across lines. Neither byte can - // start an expression, so a `<` followed by one is never a comparison; - // the closing-`>` + follow-token scan still runs, as in every other arm, - // so an unterminated `<` stays unclaimed. - b'|' | b'&' => scan_for_closing_angle_bracket(bytes, pos), + // A second `<` — the tail of a `<<` shift token, or a spaced + // `< <` — can only open a generic function type + // (`f<(v: T) => void>()`); shift chains (`a << b > c`) never + // match its `>`-then-`(` shape. + b'<' => is_generic_function_type_start(bytes, pos + 1), + + // Object/tuple literal types — but `{`/`[` equally start object and array + // *value* literals, so `x < {a: 1}` is a comparison. Skip the balanced + // group, then only a type-continuing follow token commits: `f<{ a: T }>()` + // and `f<[T, U] | null>()` are type arguments, `x < [1] ? q : r > (t, u)` + // is a comparison whatever sits past the would-be closing `>`. + // + // Neither brace nor bracket is a shell the printer strips, so + // [`TypeArgScan::Relex`] cannot look through one the way the `(` arm does — and it + // deliberately does not grade the BODY either, though tsc's answer turns on it + // (`<[1, 2]>` and `<{ x: B }>` are types to the compiler, `<[b, c++]>` and + // `<{ ...s }>` are not). Grading it would make the relaxed reading STRICTER than + // this one on the same bytes, and that direction is unsound: the head arm here + // commits on any matching `>` that a line terminator, a `(` or a template follows, so + // tsv's own parser reads `x < { ...s } >⏎c` as a type-argument list and then REJECTS + // it — where acorn and tsc both read the comparison chain. A bare output would be one + // tsv cannot reparse, so the pair stands on every bracketed head. See + // [`TypeArgScan`]'s soundness property. + b'{' | b'[' => matching_delimiter_close(bytes, pos) + .is_some_and(|close| type_operand_follow_commits(bytes, close + 1, scan)), + + // String literal types — the same follow-token question after the literal: + // `f<'a' | 'b'>()` commits, `x < 'a' + 'b' > (t, u)` stays a comparison. + b'\'' | b'"' => skip_trivia(bytes, pos, bytes.len(), TriviaProfile::JS) + .is_some_and(|after| type_operand_follow_commits(bytes, after, scan)), + + // Template literal types — skipped interpolation-aware (the opaque + // quote-to-quote trivia scan would mis-pair backticks across a nested + // `` `${`x`}` ``), then the same follow-token question. + b'`' => { + let after = skip_template_literal(bytes, pos, bytes.len()); + type_operand_follow_commits(bytes, after, scan) + } - // Not a recognized type argument start - _ => false, + // Numeric literal types: `<42>`, `<-1>`, `<.5>` — but `x < 42` is a + // comparison, so the literal alone decides nothing. Skip it (sign and a + // missing integer part included: `DecimalLiteral :: . DecimalDigits` is a + // literal type like any other, so `f<.5>()` is an instantiation to acorn; + // `-b` skips nothing and is a unary negation, never a type), then only a + // type-continuing follow token commits: `f<-1>()`, `f<.5>()` and + // `f<0 | 1>()` are type arguments, `x < 1 + 2 > (t, u)` and + // ``x < .5 ? q : r > `t` `` stay comparisons. + // + // The head class is [`numeric_literal_starts_at`], shared with the index and + // operand sites so a literal cannot be admitted at one and refused at another. + _ if numeric_literal_starts_at(bytes, pos) => { + let after = skip_signed_numeric_literal(bytes, pos, scan); + after > pos && type_operand_follow_commits(bytes, after, scan) } + + // A leading `|`/`&` on the first union/intersection member + // (`f<| A | B>()`, `f<& A & B>()`) — the form prettier itself emits + // whenever such a type argument breaks across lines. Neither byte can + // start an expression, so a `<` followed by one is never a comparison; + // the closing-`>` + follow-token scan still runs, as in every other arm, + // so an unterminated `<` stays unclaimed. + b'|' | b'&' => scan_for_closing_angle_bracket(bytes, pos, scan), + + // Not a recognized type argument start + _ => false, } } @@ -169,7 +339,12 @@ impl<'a, 'arena> Parser<'a, 'arena> { /// `p < keyof.a > (t, u)` as a comparison on the VALUE `keyof.a` and `p < keyof > (t, u)` /// as one on the value `keyof`. All four contextual operators are ordinary names there; /// the reserved `typeof`'s no-operand shapes are errors in both readings. -fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> bool { +fn type_operator_commits( + bytes: &[u8], + op: TypeOperator, + kw_start: usize, + scan: TypeArgScan, +) -> bool { let after_kw = skip_whitespace_and_comments(bytes, skip_identifier(bytes, kw_start)); match op { @@ -178,7 +353,7 @@ fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> boo // only the closing-`>` scan decides. TypeOperator::Keyof | TypeOperator::Unique => { can_start_type_operand(bytes, after_kw) - && scan_for_closing_angle_bracket(bytes, kw_start) + && scan_for_closing_angle_bracket(bytes, kw_start, scan) } // The operand is an entity name (`x`, `Ns.x`) or an `import('m')` head with a @@ -205,7 +380,7 @@ fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> boo } else { head_end }; - type_operand_follow_commits(bytes, skip_qualified_tail(bytes, after_head)) + type_operand_follow_commits(bytes, skip_qualified_tail(bytes, after_head), scan) } // The operand is a lone binding identifier (never qualified). Skip it and ask the @@ -214,7 +389,7 @@ fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> boo // at all — is a comparison on the value `infer`. TypeOperator::Infer => { identifier_starts_at(bytes, after_kw) - && type_operand_follow_commits(bytes, skip_identifier(bytes, after_kw)) + && type_operand_follow_commits(bytes, skip_identifier(bytes, after_kw), scan) } // The operand is an array/tuple type: an element type reference (`readonly T[]`, @@ -234,7 +409,7 @@ fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> boo } else { return false; }; - type_operand_follow_commits(bytes, after_head) + type_operand_follow_commits(bytes, after_head, scan) } } } @@ -251,7 +426,7 @@ fn type_operator_commits(bytes: &[u8], op: TypeOperator, kw_start: usize) -> boo /// Otherwise the leading word is a type reference: after scanning the full /// qualified name (e.g., `Ns.Type.Sub`), the shared follow-token filter /// [`type_operand_follow_commits`] decides. -fn check_identifier_type_arg_pattern(bytes: &[u8], pos: usize) -> bool { +fn check_identifier_type_arg_pattern(bytes: &[u8], pos: usize, scan: TypeArgScan) -> bool { // The leading identifier's end is located once and reused by the keyword // dispatch below and by the qualified-name loop's first step. let end = skip_identifier(bytes, pos); @@ -260,14 +435,16 @@ fn check_identifier_type_arg_pattern(bytes: &[u8], pos: usize) -> bool { // a valid type (scan decides); `new`/`abstract new` require the construct // shape so `f(x)` and `a < new B() > (c)` stay comparisons. match &bytes[pos..end] { - b"import" => return scan_for_closing_angle_bracket(bytes, pos), + b"import" => return scan_for_closing_angle_bracket(bytes, pos, scan), b"new" => { return is_construct_type_start(bytes, pos) - && scan_for_closing_angle_bracket(bytes, pos); + && scan_for_closing_angle_bracket(bytes, pos, scan); } b"abstract" => { let after = skip_whitespace_and_comments(bytes, end); - if is_construct_type_start(bytes, after) && scan_for_closing_angle_bracket(bytes, pos) { + if is_construct_type_start(bytes, after) + && scan_for_closing_angle_bracket(bytes, pos, scan) + { return true; } // A bare `abstract` is an ordinary type reference — fall through. @@ -277,7 +454,7 @@ fn check_identifier_type_arg_pattern(bytes: &[u8], pos: usize) -> bool { // Skip any qualified parts past the leading identifier (already located as // `end`, e.g. `Namespace.Type.SubType`), then ask the shared follow filter. - type_operand_follow_commits(bytes, skip_qualified_tail(bytes, end)) + type_operand_follow_commits(bytes, skip_qualified_tail(bytes, end), scan) } /// Whether the first significant token at/after `after_operand` can CONTINUE a @@ -294,8 +471,16 @@ fn check_identifier_type_arg_pattern(bytes: &[u8], pos: usize) -> bool { /// ``p < string ? q : r > `t` `` and `x < 1 + 2 > (t, u)` comparisons (matching /// acorn) even though a template tag / `(` does not start an expression and would /// otherwise let the closing-`>` scan commit. -fn type_operand_follow_commits(bytes: &[u8], after_operand: usize) -> bool { - let pos = skip_whitespace_and_comments(bytes, after_operand); +/// +/// The operand's own end moves under [`TypeArgScan::Relex`]: what the printed form does not +/// hold between the operand and this token is stepped over first +/// ([`skip_relex_operand_suffixes`]). +fn type_operand_follow_commits(bytes: &[u8], after_operand: usize, scan: TypeArgScan) -> bool { + let pos = skip_relex_operand_suffixes( + bytes, + skip_whitespace_and_comments(bytes, after_operand), + scan, + ); if pos >= bytes.len() { return false; } @@ -309,7 +494,7 @@ fn type_operand_follow_commits(bytes: &[u8], after_operand: usize) -> bool { // for the matching `>` — which rejects a trailing identifier, so `a < b > c` // and `a < b < c` stay comparisons. (`,` `|` `&` are neutral to the scan, so // starting at `pos` is equivalent to starting past the separator.) - b'>' | b'<' | b',' | b'|' | b'&' => scan_for_closing_angle_bracket(bytes, pos), + b'>' | b'<' | b',' | b'|' | b'&' => scan_for_closing_angle_bracket(bytes, pos, scan), // Indexed type vs array access: `T[K]` vs `arr[0]`. Confirmed by the same // closing-`>` scan as the arms above — `T[K]` shaped bytes are equally a @@ -318,22 +503,30 @@ fn type_operand_follow_commits(bytes: &[u8], after_operand: usize) -> bool { // `a < B[c] > d` stay comparisons, `f(x)` is an instantiation. // // A `[` past a line terminator is no index at all: the type grammar takes its - // postfix operators on the operand's own line (tsc `parsePostfixTypeOrHigher`, - // acorn-typescript `tsParseArrayTypeOrHigher` — both gate on - // `hasPrecedingLineBreak`), and so does [`Parser::parse_type`]. Committing to + // postfix operators on the operand's own line (tsc and acorn-typescript alike — the + // loop in each is named in `docs/conformance_prettier_ts.md` §Relational chain + // type-argument parens), and so does [`Parser::parse_type`]. Committing to // type arguments here would hand that parser a `` it stops reading at // `B` — `a <⏎B // c⏎[c] >⏎d` is the comparison the same bytes on one line are. + // + // That break is exactly what the PRINTER folds away, which is why the + // [`TypeArgScan::Relex`] reading passes the gate: `fn(t, u)` parses as a + // comparison chain and prints as `fn < A[T] > (t, u)`, whose region is a + // type-argument list. See [`TypeArgScan`]. b'[' => { - !has_line_terminator_between(bytes, after_operand, pos) - && check_indexed_type_pattern(bytes, pos) - && scan_for_closing_angle_bracket(bytes, pos) + !(scan.reads_source_as_written() + && has_line_terminator_between(bytes, after_operand, pos)) + && check_indexed_type_pattern(bytes, pos, scan) + && scan_for_closing_angle_bracket(bytes, pos, scan) } // Type constraint: `T extends U`. Whole-word — an identifier that merely // starts with `extends` is an ordinary operand (`a < b` ⏎ `extendsFoo()`, // where ASI ends the statement) — and confirmed by the closing-`>` scan // like every sibling arm. - b'e' if is_word_at(bytes, pos, b"extends") => scan_for_closing_angle_bracket(bytes, pos), + b'e' if is_word_at(bytes, pos, b"extends") => { + scan_for_closing_angle_bracket(bytes, pos, scan) + } _ => false, } @@ -352,20 +545,20 @@ fn type_operand_follow_commits(bytes: &[u8], after_operand: usize) -> bool { /// - `a[b - 1]`, `a[0 + 1]`, `a[c || d]`, `a[c <= d]`: arithmetic, or a /// logical/shift/relational operator — an expression, never a type → array access /// - `a[-b]`: a unary negation, not a negative literal → array access -fn check_indexed_type_pattern(bytes: &[u8], pos: usize) -> bool { +fn check_indexed_type_pattern(bytes: &[u8], pos: usize, scan: TypeArgScan) -> bool { let inside = skip_whitespace_and_comments(bytes, pos + 1); // Empty brackets `T[]` — array type if bytes.get(inside) == Some(&b']') { return true; } - index_operand_is_type(bytes, inside, b']') + index_operand_is_type(bytes, inside, b']', scan) } /// Whether the operand at `inside` — the first byte of an index, or of a paren shell /// inside one — reads as a TYPE up to `closer` (`]` for the index itself, `)` for a /// shell), on the same rule at both depths so a shell cannot admit what its index /// refuses, or refuse what it admits. -fn index_operand_is_type(bytes: &[u8], inside: usize, closer: u8) -> bool { +fn index_operand_is_type(bytes: &[u8], inside: usize, closer: u8, scan: TypeArgScan) -> bool { let Some(&first) = bytes.get(inside) else { return false; }; @@ -382,8 +575,8 @@ fn index_operand_is_type(bytes: &[u8], inside: usize, closer: u8) -> bool { // and what follows the shell continues the type or does not (`T[(A | B)[]]`). b'(' => matching_delimiter_close(bytes, inside).is_some_and(|close| { let content = skip_whitespace_and_comments(bytes, inside + 1); - index_operand_is_type(bytes, content, b')') - && continues_as_type(bytes, close + 1, closer) + index_operand_is_type(bytes, content, b')', scan) + && continues_as_type(bytes, close + 1, closer, scan) }), // Numeric literal index: `T[0]`, `T[-1]`, `T[.5]`, `T[0 | 1]`. A numeric @@ -394,14 +587,14 @@ fn index_operand_is_type(bytes: &[u8], inside: usize, closer: u8) -> bool { // answered twice (`f<.5>()` and `f()` are both instantiations to // acorn, and only this arm sees the second). _ if numeric_literal_starts_at(bytes, inside) => { - let after_number = skip_numeric_literal(bytes, inside); + let after_number = skip_signed_numeric_literal(bytes, inside, scan); // No literal starts here at all (`-b`) — a unary negation, so the index is // an expression. Guarding on this is what stops the `-` from swallowing an // identifier and landing on the same `]` a real literal ends at. if after_number == inside { return false; } - continues_as_type(bytes, after_number, closer) + continues_as_type(bytes, after_number, closer, scan) } // String literal key: `T["key"]`, `T['key']` — indexed access type @@ -417,7 +610,7 @@ fn index_operand_is_type(bytes: &[u8], inside: usize, closer: u8) -> bool { return true; } - continues_as_type(bytes, after_id, closer) + continues_as_type(bytes, after_id, closer, scan) } // Unknown pattern — default to NOT type args (safer for JS expressions) @@ -611,22 +804,34 @@ fn numeric_literal_starts_at(bytes: &[u8], pos: usize) -> bool { /// the next token, because a `[` continuation is legal only on the operand's line (see the /// `[` arm of [`type_operand_follow_commits`]); a `[` past a line terminator is where the /// index ends, so it is graded as the "anything else" arm. -fn continues_as_type(bytes: &[u8], operand_end: usize, closer: u8) -> bool { +fn continues_as_type(bytes: &[u8], operand_end: usize, closer: u8, scan: TypeArgScan) -> bool { let after_operand = skip_whitespace_and_comments(bytes, operand_end); match bytes.get(after_operand) { Some(&c) if c == closer => { - let after_close = skip_whitespace_and_comments(bytes, after_operand + 1); if closer == b')' { // The shell closed; what follows IT continues the index operand // (`(A | B)[]`, `(A)`), graded from the `)` as the operand's end. - return continues_as_type(bytes, after_operand + 1, b']'); + return continues_as_type(bytes, after_operand + 1, b']', scan); } + // Past the index's own `]`, the relexing reading steps over what the printed + // form does not hold between the operand and the token that settles it: a `)` + // closing a shell the printer strips (`(a < B[c]) > d` prints as + // `a < B[c] > d`) and a non-null `!`, which is a type to tsc and to no one + // else (`a < B[c]! > d`). See [`TypeArgScan`]. + let after_close = skip_relex_operand_suffixes( + bytes, + skip_whitespace_and_comments(bytes, after_operand + 1), + scan, + ); // Type args end with `>`, continue with `,`, or chain another index group // (`T[K][J]`, on the same line) — the caller's closing-`>` scan arbitrates // all three match bytes.get(after_close) { Some(b'>' | b',') => true, - Some(b'[') => !has_line_terminator_between(bytes, after_operand + 1, after_close), + Some(b'[') => { + !(scan.reads_source_as_written() + && has_line_terminator_between(bytes, after_operand + 1, after_close)) + } _ => false, } } @@ -639,7 +844,10 @@ fn continues_as_type(bytes: &[u8], operand_end: usize, closer: u8) -> bool { // nested index (`T[A[B]]`), a qualified name (`T[A.B]`), a generic reference // (`T[A]`), or a conditional (`T[A extends B ? C : D]`). None of these can be // arithmetic, so hand the decision to the caller's closing-`>` scan. - Some(b'[') => !has_line_terminator_between(bytes, operand_end, after_operand), + Some(b'[') => { + !(scan.reads_source_as_written() + && has_line_terminator_between(bytes, operand_end, after_operand)) + } Some(b'|' | b'&' | b'.' | b'<') => true, Some(b'e') if is_word_at(bytes, after_operand, b"extends") => true, // Anything else after the operand (e.g. `b - 1]`) is arithmetic — an expression, @@ -648,3 +856,54 @@ fn continues_as_type(bytes: &[u8], operand_end: usize, closer: u8) -> bool { _ => false, } } + +/// Step past what stands between an operand and the token that settles the region, but is +/// invisible to the reading that grades the PRINTED form. Two bytes qualify, and the loop +/// alternates because either can wrap the other (`(b)!`, `(b!)`, `b!!`, `((b))`): +/// +/// - a **`)` closing a paren SHELL the printer strips** — not in the graded form, so a `)` +/// the region did not open neither ends an operand nor ends the region (`(a < b) > c` +/// prints as `a < b > c`, whose `<`…`>` region IS a type-argument list). Without it the +/// pair this reading justifies would erase itself on the next pass, since tsv's own +/// output is the shell-bearing spelling. +/// - a **non-null `!`** — `T!` is tsc's JSDoc non-nullable type, so `` is a +/// type-argument list to the compiler while acorn-typescript, tsv's parse oracle, reads a +/// comparison. `!=` / `!==` are operators and stop the walk. +/// +/// The identity under [`TypeArgScan::Parse`], where the same `)` ends a call or a group for +/// real and the same `!` is a non-null assertion on a VALUE. +#[inline] +fn skip_relex_operand_suffixes(bytes: &[u8], mut pos: usize, scan: TypeArgScan) -> usize { + if scan.reads_source_as_written() { + return pos; + } + loop { + match bytes.get(pos) { + Some(b')') => pos = skip_whitespace_and_comments(bytes, pos + 1), + Some(b'!') if bytes.get(pos + 1) != Some(&b'=') => { + pos = skip_whitespace_and_comments(bytes, pos + 1); + } + _ => return pos, + } + } +} + +/// Skip a numeric literal with its optional sign — the type-argument lookahead's own +/// wrapper over [`skip_numeric_literal`], reporting "nothing skipped" (the position it was +/// given) where no literal begins, exactly as that function does. +/// +/// Under [`TypeArgScan::Relex`] it tolerates trivia between the sign and the digits — one of +/// the printer moves [`TypeArgScan`] enumerates: `fn<-⏎⏎1>(t)` is a comparison chain, whose +/// printed form is `fn < -1 > t` — one literal type in the region, and a `<` that would +/// re-lex. Grading the source bytes there instead takes two passes to reach the pair, which +/// a blank-injection run reads as a non-idempotency. +#[inline] +fn skip_signed_numeric_literal(bytes: &[u8], pos: usize, scan: TypeArgScan) -> usize { + let end = skip_numeric_literal(bytes, pos); + if end > pos || scan.reads_source_as_written() || bytes.get(pos) != Some(&b'-') { + return end; + } + let after_sign = skip_whitespace_and_comments(bytes, pos + 1); + let end = skip_numeric_literal(bytes, after_sign); + if end > after_sign { end } else { pos } +} diff --git a/crates/tsv_ts/src/parser/mod.rs b/crates/tsv_ts/src/parser/mod.rs index c1a5cbce4..7c241861d 100644 --- a/crates/tsv_ts/src/parser/mod.rs +++ b/crates/tsv_ts/src/parser/mod.rs @@ -638,6 +638,30 @@ impl<'a, 'arena> Parser<'a, 'arena> { (self.base_offset + raw) as u32 } + /// The inverse of [`Parser::span_pos`]: an absolute `Span` coordinate back to a raw + /// offset into `self.source`. + /// + /// Stored spans are **host** coordinates while `self.source` is the local (possibly + /// embedded) slice, so a span read back as an index has to shift — indexing with one + /// directly reads the wrong bytes under Svelte embedding, or past the slice end. The + /// same hazard [`Parser::resolve_cooked`] names, and the reason a byte scan keyed on a + /// node's span goes through here. + /// + /// A position BELOW the base is the wrong base, not a clamp: the saturation would hand + /// back offset 0, where a byte scan simply finds nothing and reports no verdict — + /// exactly the silent miss this function exists to prevent. Asserted rather than + /// returned, since every caller holds a span this parser itself produced. + #[inline] + pub(super) fn local_pos(&self, span_pos: u32) -> usize { + debug_assert!( + span_pos as usize >= self.base_offset, + "span position {span_pos} is below the parser's base offset {} — a host \ + coordinate from another parse, or a base that moved", + self.base_offset, + ); + (span_pos as usize).saturating_sub(self.base_offset) + } + /// Get the end position of the previously consumed token (with base_offset). /// /// Useful for determining where statements end after consuming optional tokens diff --git a/crates/tsv_ts/src/printer/needs_parens.rs b/crates/tsv_ts/src/printer/needs_parens.rs index 659491b18..3e4b6d744 100644 --- a/crates/tsv_ts/src/printer/needs_parens.rs +++ b/crates/tsv_ts/src/printer/needs_parens.rs @@ -616,6 +616,14 @@ fn is_unary_or_update(expr: &Expression<'_>) -> bool { /// /// Every other operator lets all three backtrack to the type arguments, which is what makes /// the bare spelling AST-identical there. +/// +/// This is the TAIL half of the `canFollowTypeArgumentsInExpression` seam — an operand that +/// ENDS on a `>`. Its DUAL, an operand that ends on the `>`'s left and whose own `<`…`>` +/// region would re-lex as the argument list, lives in the arm of +/// [`needs_parens_binary_operand`] keyed on +/// `internal::BinaryExpression::relexes_as_type_arguments`. Neither half is derivable from +/// the other, and a change to one is a question about the other: the two are findable from +/// here and from there, and nowhere else. pub(in crate::printer) const fn joins_a_trailing_angle_bracket(op: BinaryOperator) -> bool { matches!( op, @@ -949,6 +957,37 @@ fn needs_parens_binary_operand( return true; } + // The DUAL of the arm above, read off the same `canFollowTypeArgumentsInExpression` + // seam from the other side. There the operand IS an instantiation and the operator's + // first token re-lexes its closing `>`; here the operand is a relational `<` chain + // whose own printed `<`…`>` region would BE a type-argument list, and the enclosing + // `>` is the close. `(fn < A[T]) > (t, u)` and `(x < y) > { a: 1 }` are the same tree + // in the spelling every parser reads alike; bare, both re-parse as something else — + // a `CallExpression` with type arguments where the printer folded the author's break + // away, an instantiation plus a free-standing statement where it added one of its own + // (past a line break tsv's own parse commits the list ahead of any expression, so + // width alone reaches it; which followers commit, for each parser, is stated in the + // catalog entry). Prettier strips the pair at both, a cataloged ◆prettier_bug. + // + // The axis is the JOIN of two tokens, not the operand's node — the same doctrine — so + // the question was answered where the tokens still exist: the parser recorded it on + // the `<` node (`BinaryExpression::relexes_as_type_arguments`), at the `>` that closes + // the region. It is deliberately LAYOUT-BLIND: whether the `>` ends a line is + // unknowable here, so the pair stands at every width, the ones that never break + // included. And it is REGION-keyed rather than shape-keyed: an operand that is no type + // keeps the chain bare, whatever it is parenthesized with. + if !is_right + && parent_op == BinaryOperator::GreaterThan + && matches!( + expr, + Expression::BinaryExpression(child) + if child.operator == BinaryOperator::LessThan + && child.relexes_as_type_arguments + ) + { + return true; + } + let Expression::BinaryExpression(child) = expr else { return false; }; diff --git a/deno.json b/deno.json index efbbfb430..ada4a4419 100644 --- a/deno.json +++ b/deno.json @@ -88,7 +88,8 @@ "discovery:audit": "deno run --allow-read --allow-env --allow-run=cargo,git scripts/discovery_audit.ts", "binding:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet binding_audit --gate", "authoring:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet authoring_audit", - "paren:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet paren_audit", + "//paren:audit": "`--require-relational` is the audit's SEED-SET vacuity floor, and this is the invocation entitled to it: the relational `<`…`>` class lives in tests/fixtures (typescript/expressions/binary/relational_*) and essentially nowhere else, so a run over the fixture tree that enumerates ZERO relational sites means the class stopped enumerating. The real-code leg of `audit:corpus` (benches/js/corpus_audit.ts, publish Step 3c) deliberately does NOT pass it — nobody writes `a < b > c` in real code, both relational rows are legitimately 0 over the ../corpora snapshot, and a floor there fails a clean run. A flag rather than a paths-contains-tests/fixtures sniff, because a sniff answers wrongly on a subtree run; a NARROWED run under the flag fails its floor by design, like a ratchet refusing a narrowed `:update`, and drops the flag instead. The TOTAL floor (any site at all) stays unconditional in the audit.", + "paren:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet paren_audit --require-relational", "render:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet render_audit --gate", "fuzz:audit": "cargo run --profile corpus -p tsv_debug --features audits --quiet fuzz --seed 0 --iterations 5000", "idempotency:sweep": "deno run --allow-read --allow-env --allow-sys --allow-run=cargo,git --config benches/js/deno.json benches/js/idempotency_sweep.ts", diff --git a/docs/conformance_prettier.md b/docs/conformance_prettier.md index c80e48bb2..538c427f4 100644 --- a/docs/conformance_prettier.md +++ b/docs/conformance_prettier.md @@ -53,6 +53,7 @@ The fixture-pinned `◆prettier_bug` cases — where Prettier produces output th - Constrained `infer … extends` operand parens — strips required parens → output fails to re-parse — [constrained_extends_parens](../tests/fixtures/typescript/types/infer/constrained_extends_parens_prettier_divergence/) - Negative literal type sign comment (`-/* c */ 1`) — *adds* parens to hold the comment (`-(/* c */ 1)`), but no such type exists: `-` is a negative literal type only when the next token is a numeric/bigint literal → output fails to re-parse — [negative_literal_sign_comment](../tests/fixtures/typescript/types/negative_literal_sign_comment_prettier_divergence/) - TS instantiation parens (`(x ? y : z)`) — strips parens, semantic change — [instantiation_parens](../tests/fixtures/typescript/typescript_specific/assertions/instantiation_parens_prettier_divergence/); the class-operand / `export default` case (`export default (class {})`) is worse still (strips → a class _declaration_) — [export_default_instantiation](../tests/fixtures/typescript/modules/exports/default_wrappable_leftmost_operators/instantiation_prettier_divergence/); the pair AROUND one (`(fn) + 1`, `(fn) >= 1`, `(fn)!`) — strips it too, and WHICH oracle refuses the stripped form splits the class three ways: `fn + 1` re-parses everywhere as the comparison chain `fn < T > +1` (semantic change, printed that way on prettier's own next pass); `fn > 1`, `>> 1`, `>>> 1` and `fn!` no parser accepts, so that output fails to re-parse outright; and `fn < 1` / `fn >= 1` only **tsc** rejects (TS1005 `'>' expected`, TS1109 `Expression expected`) — acorn-typescript, tsv's parse oracle and the parser Svelte itself uses, reads both as instantiation expressions, so prettier throws on its own output (its TypeScript parser is tsc's) where tsv accepts it and puts the pair back. `fn << 1` is the mirror, tsc's instantiation and acorn's reject — [instantiation_paren_follow](../tests/fixtures/typescript/typescript_specific/generics/instantiation_paren_follow_prettier_divergence/) +- Relational chain printed into a type-argument list — the dual of the entry above, at the same `canFollowTypeArgumentsInExpression` seam: a comparison chain whose `<`…`>` region would parse as a type-argument list re-lexes as an instantiation the moment the printer touches a line break near it. Removing one does it (`fn(t, u)` is the chain `(fn < A[T]) > (t, u)` only because the newline holds `[T]` to an index — folded, the output is a `CallExpression`), and so does adding one (a break after the `>` settles the list — from an object's own forced break, or from **width alone** on plain identifiers, where prettier's own second pass writes the loss out as `aaa;` plus `ccc;`). Which object shapes end worse still is stated in the object fixture's README. tsv keeps the pair around the `>`'s left operand, at every follower past the `>`: tsv's own parse commits the list past a break ahead of any expression, so the follower protects nothing (the catalog entry states which followers commit, for which parser) — [relational_chain_type_arg_parens](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/), [relational_chain_type_arg_parens_object_long](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/), [relational_chain_type_arg_parens_long](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/), [relational_chain_type_arg_parens_close_follow](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/) - Svelte destructuring rename-with-default key drop (`{ a: b = 1 }` → `{ b = 1 }`) — semantic change — [each](../tests/fixtures/svelte/blocks/each/destructure_rename_default_prettier_divergence/), [await](../tests/fixtures/svelte/blocks/await/destructure_rename_default_prettier_divergence/) - `x?.#a` (optional chain to private field) — throws on valid input (pinned by `prettier_rejects.txt`) — [private_fields_optional_chain](../tests/fixtures/typescript/declarations/class/private_fields_optional_chain_prettier_divergence/) - JSDoc cast + an enclosing paren — emits the paren *between* the comment and its `(`, so the cast re-binds to the wider expression; non-idempotent, and a **semantic** change (oxfmt and biome share the bug) — [jsdoc_type_cast_enclosing_parens](../tests/fixtures/typescript/syntax/comments/jsdoc_type_cast_enclosing_parens_prettier_divergence/) diff --git a/docs/conformance_prettier_ts.md b/docs/conformance_prettier_ts.md index ef70879ef..6d3e6887f 100644 --- a/docs/conformance_prettier_ts.md +++ b/docs/conformance_prettier_ts.md @@ -12,6 +12,7 @@ governs every entry here live in [conformance_prettier.md](./conformance_prettie - Return type generic union — ◆print_width — [return_type_generic_union_long](../tests/fixtures/typescript/declarations/function/return_type_generic_union_long_prettier_divergence/) - Module path calls — ◆print_width — [path_calls_long](../tests/fixtures/typescript/modules/imports/path_calls_long_prettier_divergence/) - Instantiation expression parens — ◆prettier_bug — [instantiation_parens](../tests/fixtures/typescript/typescript_specific/assertions/instantiation_parens_prettier_divergence/), [export_default_instantiation](../tests/fixtures/typescript/modules/exports/default_wrappable_leftmost_operators/instantiation_prettier_divergence/), [instantiation_paren_follow](../tests/fixtures/typescript/typescript_specific/generics/instantiation_paren_follow_prettier_divergence/) +- Relational chain type-argument parens — ◆prettier_bug — [relational_chain_type_arg_parens](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/), [relational_chain_type_arg_parens_object_long](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/), [relational_chain_type_arg_parens_long](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/), [relational_chain_type_arg_parens_close_follow](../tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/) - Non-null parenthesized base — ◆design_choice — [non_null_paren_base_long](../tests/fixtures/typescript/expressions/member/non_null_paren_base_long_prettier_divergence/) - Parenthesized binary member base — ◆design_choice ◆print_width — [paren_binary_base_long](../tests/fixtures/typescript/expressions/member/paren_binary_base_long_prettier_divergence/) - Constrained infer extends-operand parens — ◆prettier_bug — [constrained_extends_parens](../tests/fixtures/typescript/types/infer/constrained_extends_parens_prettier_divergence/) @@ -31,6 +32,211 @@ governs every entry here live in [conformance_prettier.md](./conformance_prettie **Instantiation expression parens**: Prettier strips parentheses from ternary and binary expressions in `TSInstantiationExpression` (`(x ? y : z)` → `x ? y : z`), changing semantics. Without parens, `` only applies to the last operand. tsv preserves parens to maintain the original meaning. Both formatters agree on preserving parens for assignment expressions (`(x = y)`). A class-expression operand in `export default` position — `export default (class {})` — is the same bug but sharper: stripping the parens makes the leading `class {}` a class _declaration_, so Prettier's output re-parses to a `ClassDeclaration` plus a dangling `;` statement (a different AST), while tsv keeps the parens (adjudicated by `export_default_needs_parens`; see [export_default_instantiation](../tests/fixtures/typescript/modules/exports/default_wrappable_leftmost_operators/instantiation_prettier_divergence/)). The pair AROUND an instantiation is the mirror case: Prettier strips it whatever token follows, but a type argument list is only read as one where the next token cannot continue a comparison chain (tsc's `canFollowTypeArgumentsInExpression`) — `fn + 1` re-parses as `fn < T > +1` (a different program, which Prettier's own second pass then prints), and `fn < 1` / `> 1` / `>= 1` / `>> 1` / `>>> 1`, `fn!` and `fn++` do not parse at all under tsc. tsv keeps the pair ahead of exactly those followers — `+`, `-`, `<`, `>`, `>=`, `>>`, `>>>`, `<<` (which tsc reads as an instantiation but acorn-typescript, tsv's parse oracle, rejects), a non-null `!` (`(fn)!.prop` included, where the chain would otherwise drop the type arguments) and a postfix `++` / `--` — and strips it ahead of every other operator, the set [instantiation_operator_follow](../tests/fixtures/typescript/typescript_specific/generics/instantiation_operator_follow/) pins from the bare side — alongside the `input_invalid_*` files there, which carry the followers neither parser admits. The axis is the join of two tokens, not the operand's node: an operand that merely ENDS on the close — a binary's right operand (`a * fn + 1`, `1 + fn + 2`), a prefix operator's argument (`-fn + 1`), an angle-bracket assertion's operand (`fn + 1`) — re-lexes the same way, so the pair wraps that whole operand (`(a * fn) + 1`, `(fn) + 1`), and a pair authored around the instantiation alone moves out to it. The walk stops at a child that takes its own pair by precedence in that position, which ends the operand on a `)` instead: `(fn) + 1` keeps only the inner pair, and both formatters agree. `as` / `satisfies` end on a TYPE rather than on an expression, so they are never in the class (`ends_with_instantiation_close`; see [instantiation_paren_follow](../tests/fixtures/typescript/typescript_specific/generics/instantiation_paren_follow_prettier_divergence/)). The bare side of two of those followers is tsv's own: `fn < 1` and `fn >= 1` ARE instantiation expressions to acorn-typescript — tsv's parse oracle, and the parser Svelte itself uses — where tsc's grammar rejects them (TS1005 `'>' expected.`, TS1109 `Expression expected.`), so tsv accepts them and the formatter REPAIRS them to `(fn) < 1` and `(fn) >= 1`, the same tree in the spelling every parser reads alike. Accepting therefore costs nothing downstream, while rejecting would refuse a ` diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/output_prettier.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/output_prettier.svelte new file mode 100644 index 000000000..a21d971d3 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_close_follow_prettier_divergence/output_prettier.svelte @@ -0,0 +1,28 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/README.md b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/README.md new file mode 100644 index 000000000..19774da4c --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/README.md @@ -0,0 +1,27 @@ +# relational_chain_type_arg_parens_long_prettier_divergence + +Width alone re-lexes a bare relational chain, and prettier takes the break without the pair that makes it safe. + +tsv: `(aaa… < bbb…) >⏎ccc…` +Prettier: `aaa… <⏎bbb… >⏎ccc…`, which its own second pass writes out as `aaa…;` plus `ccc…;` + +## Reason + +**Semantic preservation.** Ahead of an identifier, a line terminator after the `>` settles the list as type arguments, to tsv, acorn-typescript and tsc alike (which followers a break commits, for which parser, is stated in the catalog entry linked below). Nothing else has to be unusual: three plain identifiers over 100 columns are enough, with no comment, blank line or object anywhere in the statement. Once the printer breaks the chain one operand per line, `aaa < bbb > ccc` re-parses as a `TSInstantiationExpression` plus a separate expression statement — two `BinaryExpression` nodes gone. Prettier's own second pass writes that out, pinned by `audit_signature.txt`. + +tsv keeps a pair around the `>`'s left operand, which takes the region out of type-argument position at every layout. The pair is **layout-blind** — whether the `>` ends a line is not knowable where parens are decided — so `l1`, which never breaks, carries it too. + +`input.svelte` pins the **post-fix layout boundary** — the one a fixture whose input is tsv's own fixed point can hold. With the pair, `l1`'s continuation line is exactly 100 columns and holds the chain flat; `l2`'s would be 101 and breaks after the `>`, the first layout that puts a line terminator at the join. `l3` is wide enough that the operands break one per line, which is the shape that loses nodes today. + +## Where the loss begins + +The **bug boundary** is a different width, and no cell of `input.svelte` can carry it: the pair costs two columns, so a cell whose bare form measures 100 has a paired form of 102 — already broken, with no "stays flat" left to claim. Measured on the bare spelling prettier emits, three plain identifiers on one `const` continuation line: + +- **100 columns** — `aaa…(29) < bbb…(29) > ccc…(31);` stays flat, and re-parses as the program that was written: `BinaryExpression >` over `BinaryExpression <`. +- **101 columns** — `aaa…(29) < bbb…(29) > ccc…(32);` breaks one operand per line, and re-parses as a `TSInstantiationExpression` plus a separate `ExpressionStatement`. Both `BinaryExpression` nodes are gone. + +`output_prettier.svelte`'s own width cells sit just under that line: bare, `l1` measures 98 and `l2` 99, both flat and both still the comparison chain — so neither shows the loss. `l3` is the cell that crosses it. Bare, its operands break one per line (52 / 52 / 51 columns) and the re-parse is the instantiation plus the free statement, which is what `audit_signature.txt` pins prettier's second pass writing out. + +The as-authored half of the same bug (a break the printer REMOVES rather than adds) is [relational_chain_type_arg_parens](../relational_chain_type_arg_parens_prettier_divergence/); the object-operand half, where prettier's pass-1 output can end worse still, is [relational_chain_type_arg_parens_object_long](../relational_chain_type_arg_parens_object_long_prettier_divergence/). + +See [conformance_prettier.md](../../../../../../docs/conformance_prettier.md) §Prettier bug index and [conformance_prettier_ts.md](../../../../../../docs/conformance_prettier_ts.md) §TypeScript (Relational chain type-argument parens). diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/audit_signature.txt b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/audit_signature.txt new file mode 100644 index 000000000..2a4adea32 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/audit_signature.txt @@ -0,0 +1,29 @@ +# Auto-generated prettier chain signature. Do not edit manually. +# Regenerate: deno task fixtures:update:formatted +# +# Each %%PASS=N%% section is exactly prettier^N(output_prettier.). +# This file exists when prettier is non-idempotent on output_prettier.* — it pins +# the full chain so the audit recognizes the case and the validator catches drift. +# See docs/fixture_overview.md (rule F4) and crates/tsv_debug/src/fixtures/audit_signature.rs. + +%%PASS=2 (fixed point)%% + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/expected.json b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/expected.json new file mode 100644 index 000000000..6008aad4f --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/expected.json @@ -0,0 +1,636 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 1070, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " Width alone re-lexes a bare relational chain: the first break the printer takes", + "start": 20, + "end": 102, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 83 + } + } + }, + { + "type": "Line", + "value": " after the `>` makes `canFollowTypeArgumentsInExpression` read a preceding line", + "start": 104, + "end": 185, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 82 + } + } + }, + { + "type": "Line", + "value": " terminator and accept the type-argument list. The pair is layout-blind — it is", + "start": 187, + "end": 268, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 4, + "column": 82 + } + } + }, + { + "type": "Line", + "value": " there at every width, including the ones that never break.", + "start": 270, + "end": 331, + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 62 + } + } + }, + { + "type": "Line", + "value": " With the pair, the continuation line below is exactly 100 and the chain stays flat.", + "start": 334, + "end": 420, + "loc": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 7, + "column": 87 + } + } + }, + { + "type": "Line", + "value": " One character longer in the right operand than `l1`: with the pair, the flat form no", + "start": 534, + "end": 621, + "loc": { + "start": { + "line": 11, + "column": 1 + }, + "end": { + "line": 11, + "column": 88 + } + } + }, + { + "type": "Line", + "value": " longer fits, so the break lands after the `>` — the join the pair protects.", + "start": 623, + "end": 701, + "loc": { + "start": { + "line": 12, + "column": 1 + }, + "end": { + "line": 12, + "column": 79 + } + } + }, + { + "type": "Line", + "value": " Wider still, the operands break one per line and the `<` operand hangs.", + "start": 818, + "end": 892, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 75 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 1069, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 1060, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 22, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 422, + "end": 531, + "loc": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 9, + "column": 98 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 428, + "end": 530, + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 9, + "column": 97 + } + }, + "id": { + "type": "Identifier", + "start": 428, + "end": 430, + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 9 + } + }, + "name": "l1" + }, + "init": { + "type": "BinaryExpression", + "start": 435, + "end": 530, + "loc": { + "start": { + "line": 9, + "column": 2 + }, + "end": { + "line": 9, + "column": 97 + } + }, + "left": { + "type": "BinaryExpression", + "start": 436, + "end": 497, + "loc": { + "start": { + "line": 9, + "column": 3 + }, + "end": { + "line": 9, + "column": 64 + } + }, + "left": { + "type": "Identifier", + "start": 436, + "end": 465, + "loc": { + "start": { + "line": 9, + "column": 3 + }, + "end": { + "line": 9, + "column": 32 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 468, + "end": 497, + "loc": { + "start": { + "line": 9, + "column": 35 + }, + "end": { + "line": 9, + "column": 64 + } + }, + "name": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 501, + "end": 530, + "loc": { + "start": { + "line": 9, + "column": 68 + }, + "end": { + "line": 9, + "column": 97 + } + }, + "name": "ccccccccccccccccccccccccccccc" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " Width alone re-lexes a bare relational chain: the first break the printer takes", + "start": 20, + "end": 102 + }, + { + "type": "Line", + "value": " after the `>` makes `canFollowTypeArgumentsInExpression` read a preceding line", + "start": 104, + "end": 185 + }, + { + "type": "Line", + "value": " terminator and accept the type-argument list. The pair is layout-blind — it is", + "start": 187, + "end": 268 + }, + { + "type": "Line", + "value": " there at every width, including the ones that never break.", + "start": 270, + "end": 331 + }, + { + "type": "Line", + "value": " With the pair, the continuation line below is exactly 100 and the chain stays flat.", + "start": 334, + "end": 420 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 703, + "end": 815, + "loc": { + "start": { + "line": 13, + "column": 1 + }, + "end": { + "line": 15, + "column": 33 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 709, + "end": 814, + "loc": { + "start": { + "line": 13, + "column": 7 + }, + "end": { + "line": 15, + "column": 32 + } + }, + "id": { + "type": "Identifier", + "start": 709, + "end": 711, + "loc": { + "start": { + "line": 13, + "column": 7 + }, + "end": { + "line": 13, + "column": 9 + } + }, + "name": "l2" + }, + "init": { + "type": "BinaryExpression", + "start": 716, + "end": 814, + "loc": { + "start": { + "line": 14, + "column": 2 + }, + "end": { + "line": 15, + "column": 32 + } + }, + "left": { + "type": "BinaryExpression", + "start": 717, + "end": 778, + "loc": { + "start": { + "line": 14, + "column": 3 + }, + "end": { + "line": 14, + "column": 64 + } + }, + "left": { + "type": "Identifier", + "start": 717, + "end": 746, + "loc": { + "start": { + "line": 14, + "column": 3 + }, + "end": { + "line": 14, + "column": 32 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 749, + "end": 778, + "loc": { + "start": { + "line": 14, + "column": 35 + }, + "end": { + "line": 14, + "column": 64 + } + }, + "name": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 784, + "end": 814, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 32 + } + }, + "name": "cccccccccccccccccccccccccccccc" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " One character longer in the right operand than `l1`: with the pair, the flat form no", + "start": 534, + "end": 621 + }, + { + "type": "Line", + "value": " longer fits, so the break lands after the `>` — the join the pair protects.", + "start": 623, + "end": 701 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 894, + "end": 1059, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 21, + "column": 49 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 900, + "end": 1058, + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 21, + "column": 48 + } + }, + "id": { + "type": "Identifier", + "start": 900, + "end": 902, + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "name": "l3" + }, + "init": { + "type": "BinaryExpression", + "start": 907, + "end": 1058, + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 21, + "column": 48 + } + }, + "left": { + "type": "BinaryExpression", + "start": 908, + "end": 1006, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 20, + "column": 49 + } + }, + "left": { + "type": "Identifier", + "start": 908, + "end": 954, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 49 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 960, + "end": 1006, + "loc": { + "start": { + "line": 20, + "column": 3 + }, + "end": { + "line": 20, + "column": 49 + } + }, + "name": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1012, + "end": 1058, + "loc": { + "start": { + "line": 21, + "column": 2 + }, + "end": { + "line": 21, + "column": 48 + } + }, + "name": "cccccccccccccccccccccccccccccccccccccccccccccc" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " Wider still, the operands break one per line and the `<` operand hangs.", + "start": 818, + "end": 892 + } + ] + } + ], + "sourceType": "module" + }, + "attributes": [ + { + "type": "Attribute", + "start": 8, + "end": 17, + "name": "lang", + "name_loc": { + "start": { + "line": 1, + "column": 8, + "character": 8 + }, + "end": { + "line": 1, + "column": 12, + "character": 12 + } + }, + "value": [ + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "ts", + "data": "ts" + } + ] + } + ] + } +} diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/input.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/input.svelte new file mode 100644 index 000000000..580390871 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/input.svelte @@ -0,0 +1,22 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/output_prettier.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/output_prettier.svelte new file mode 100644 index 000000000..10d31f193 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_long_prettier_divergence/output_prettier.svelte @@ -0,0 +1,21 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/README.md b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/README.md new file mode 100644 index 000000000..08ec7b829 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/README.md @@ -0,0 +1,32 @@ +# relational_chain_type_arg_parens_object_long_prettier_divergence + +A relational chain whose right operand is an object literal reaches the same re-lex, and a worse end: prettier's output does not parse. + +tsv: `(x < y) >⏎{⏎\ta: 1,⏎⏎\tb: 2⏎}` +Prettier: `x <⏎y >⏎{⏎\ta: 1,⏎⏎\tb: 2⏎}`, which no parser accepts — prettier's own second pass throws `';' expected` + +## Reason + +**Semantic preservation.** Ahead of an object, a line terminator after the `>` settles the list as type arguments, to tsv, acorn-typescript and tsc alike (which followers a break commits, and for which parser, is stated once in the catalog entry linked below). An object literal supplies that break two ways, and both are here: a blank line inside it forces the break at every width (`c1`), and width drops it below the `>` line (`c3`). What is left after the re-lex is a `TSInstantiationExpression` followed by a free-standing block, and the object's member count decides what that block is: + +- **one member** — `x;⏎{ a: 1 };` parses, as a `BlockStatement` holding a labelled statement: a different program, not an error. +- **several members** — `x;⏎{ kkk: 1, lll: 2 };` is rejected (`Expected ';'`): output that does not parse. + +Every cell here has several members, so its output fails to re-parse outright rather than quietly becoming a different program. + +That truncation is why this fixture carries no `audit_signature.txt`: prettier throws on its own pass-1 output, so there is no chain to pin (rule F4b tolerates an erroring pass). + +tsv keeps a pair around the `>`'s left operand, which takes the region out of type-argument position whatever the layout. The pair is **layout-blind**, so `c2` — which never breaks at the join — carries it too. `input.svelte` pins the **post-fix layout boundary**: with the pair, `c2`'s continuation line is exactly 100 columns and keeps the object welded to the `>`; `c3`'s would be 101 and drops it. + +## Where the loss begins + +The **bug boundary** is two columns below that, on the bare spelling, and no cell of `input.svelte` can carry it — the pair costs two columns, so a bare-100 cell's paired form is 102 and already broken. Measured on the bare spelling, one two-key object on a `const` continuation line: + +- **100 columns** — `x < y > { kkk…(38): 1, lll…(37): 2 };` stays welded, and re-parses as the comparison chain it was written as: `BinaryExpression >` over `BinaryExpression <`, the `ObjectExpression` on the right. +- **101 columns** — `x < y > { kkk…(39): 1, lll…(37): 2 };` breaks all three operands, the object landing on its own line, and the output does not re-parse at all — Svelte's parser reports `Unexpected token`, prettier's own second pass `';' expected` — because what is left is a `TSInstantiationExpression` followed by a block whose `,`-separated members are no statement. + +`output_prettier.svelte`'s own width cells sit under that line: bare, `c2` measures 98 and `c3` 99, both welded and both still the comparison chain, so neither shows the loss on its own. `c1` needs no width for it — the blank line inside the object forces the break at every column, which is why `output_prettier.svelte` as a whole fails to re-parse. + +The plain-identifier half of the same width bug is [relational_chain_type_arg_parens_long](../relational_chain_type_arg_parens_long_prettier_divergence/); the as-authored half, where the printer REMOVES a break instead of adding one, is [relational_chain_type_arg_parens](../relational_chain_type_arg_parens_prettier_divergence/). + +See [conformance_prettier.md](../../../../../../docs/conformance_prettier.md) §Prettier bug index and [conformance_prettier_ts.md](../../../../../../docs/conformance_prettier_ts.md) §TypeScript (Relational chain type-argument parens). diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/expected.json b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/expected.json new file mode 100644 index 000000000..2dcba9c34 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/expected.json @@ -0,0 +1,973 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 1076, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " A relational chain whose right operand is an object literal keeps the same paren", + "start": 20, + "end": 103, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 84 + } + } + }, + { + "type": "Line", + "value": " pair the plain chain does, and for the sharper reason: to tsv, acorn and tsc alike, a", + "start": 105, + "end": 193, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 89 + } + } + }, + { + "type": "Line", + "value": " line terminator after the `>` commits a type-argument list ahead of an object, so any", + "start": 195, + "end": 283, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 4, + "column": 89 + } + } + }, + { + "type": "Line", + "value": " break there re-lexes the chain into an instantiation plus a free-standing block — and a", + "start": 285, + "end": 375, + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 91 + } + } + }, + { + "type": "Line", + "value": " break arrives from the object's own forced break as readily as from width.", + "start": 377, + "end": 454, + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 78 + } + } + }, + { + "type": "Line", + "value": " The blank line inside the object forces the break at every width.", + "start": 457, + "end": 525, + "loc": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 8, + "column": 69 + } + } + }, + { + "type": "Line", + "value": " With the pair, the continuation line below is exactly 100 and the object stays welded.", + "start": 579, + "end": 668, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 90 + } + } + }, + { + "type": "Line", + "value": " One character longer in the first key than `c2`: with the pair, the welded form no", + "start": 782, + "end": 867, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 86 + } + } + }, + { + "type": "Line", + "value": " longer fits, so the object drops to its own line — the break the pair survives.", + "start": 869, + "end": 951, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 83 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 1075, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 1066, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 26, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 527, + "end": 576, + "loc": { + "start": { + "line": 9, + "column": 1 + }, + "end": { + "line": 15, + "column": 4 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 533, + "end": 575, + "loc": { + "start": { + "line": 9, + "column": 7 + }, + "end": { + "line": 15, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 533, + "end": 535, + "loc": { + "start": { + "line": 9, + "column": 7 + }, + "end": { + "line": 9, + "column": 9 + } + }, + "name": "c1" + }, + "init": { + "type": "BinaryExpression", + "start": 540, + "end": 575, + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 15, + "column": 3 + } + }, + "left": { + "type": "BinaryExpression", + "start": 541, + "end": 546, + "loc": { + "start": { + "line": 10, + "column": 3 + }, + "end": { + "line": 10, + "column": 8 + } + }, + "left": { + "type": "Identifier", + "start": 541, + "end": 542, + "loc": { + "start": { + "line": 10, + "column": 3 + }, + "end": { + "line": 10, + "column": 4 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 545, + "end": 546, + "loc": { + "start": { + "line": 10, + "column": 7 + }, + "end": { + "line": 10, + "column": 8 + } + }, + "name": "y" + } + }, + "operator": ">", + "right": { + "type": "ObjectExpression", + "start": 552, + "end": 575, + "loc": { + "start": { + "line": 11, + "column": 2 + }, + "end": { + "line": 15, + "column": 3 + } + }, + "properties": [ + { + "type": "Property", + "start": 557, + "end": 561, + "loc": { + "start": { + "line": 12, + "column": 3 + }, + "end": { + "line": 12, + "column": 7 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 557, + "end": 558, + "loc": { + "start": { + "line": 12, + "column": 3 + }, + "end": { + "line": 12, + "column": 4 + } + }, + "name": "a" + }, + "value": { + "type": "Literal", + "start": 560, + "end": 561, + "loc": { + "start": { + "line": 12, + "column": 6 + }, + "end": { + "line": 12, + "column": 7 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + }, + { + "type": "Property", + "start": 567, + "end": 571, + "loc": { + "start": { + "line": 14, + "column": 3 + }, + "end": { + "line": 14, + "column": 7 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 567, + "end": 568, + "loc": { + "start": { + "line": 14, + "column": 3 + }, + "end": { + "line": 14, + "column": 4 + } + }, + "name": "b" + }, + "value": { + "type": "Literal", + "start": 570, + "end": 571, + "loc": { + "start": { + "line": 14, + "column": 6 + }, + "end": { + "line": 14, + "column": 7 + } + }, + "value": 2, + "raw": "2" + }, + "kind": "init" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A relational chain whose right operand is an object literal keeps the same paren", + "start": 20, + "end": 103 + }, + { + "type": "Line", + "value": " pair the plain chain does, and for the sharper reason: to tsv, acorn and tsc alike, a", + "start": 105, + "end": 193 + }, + { + "type": "Line", + "value": " line terminator after the `>` commits a type-argument list ahead of an object, so any", + "start": 195, + "end": 283 + }, + { + "type": "Line", + "value": " break there re-lexes the chain into an instantiation plus a free-standing block — and a", + "start": 285, + "end": 375 + }, + { + "type": "Line", + "value": " break arrives from the object's own forced break as readily as from width.", + "start": 377, + "end": 454 + }, + { + "type": "Line", + "value": " The blank line inside the object forces the break at every width.", + "start": 457, + "end": 525 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 670, + "end": 779, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 676, + "end": 778, + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "id": { + "type": "Identifier", + "start": 676, + "end": 678, + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "name": "c2" + }, + "init": { + "type": "BinaryExpression", + "start": 683, + "end": 778, + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "left": { + "type": "BinaryExpression", + "start": 684, + "end": 689, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 8 + } + }, + "left": { + "type": "Identifier", + "start": 684, + "end": 685, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 688, + "end": 689, + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 8 + } + }, + "name": "y" + } + }, + "operator": ">", + "right": { + "type": "ObjectExpression", + "start": 693, + "end": 778, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "properties": [ + { + "type": "Property", + "start": 695, + "end": 734, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 53 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 695, + "end": 731, + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 50 + } + }, + "name": "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" + }, + "value": { + "type": "Literal", + "start": 733, + "end": 734, + "loc": { + "start": { + "line": 19, + "column": 52 + }, + "end": { + "line": 19, + "column": 53 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + }, + { + "type": "Property", + "start": 736, + "end": 776, + "loc": { + "start": { + "line": 19, + "column": 55 + }, + "end": { + "line": 19, + "column": 95 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 736, + "end": 773, + "loc": { + "start": { + "line": 19, + "column": 55 + }, + "end": { + "line": 19, + "column": 92 + } + }, + "name": "lllllllllllllllllllllllllllllllllllll" + }, + "value": { + "type": "Literal", + "start": 775, + "end": 776, + "loc": { + "start": { + "line": 19, + "column": 94 + }, + "end": { + "line": 19, + "column": 95 + } + }, + "value": 2, + "raw": "2" + }, + "kind": "init" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " With the pair, the continuation line below is exactly 100 and the object stays welded.", + "start": 579, + "end": 668 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 953, + "end": 1065, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 25, + "column": 89 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 959, + "end": 1064, + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 25, + "column": 88 + } + }, + "id": { + "type": "Identifier", + "start": 959, + "end": 961, + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 9 + } + }, + "name": "c3" + }, + "init": { + "type": "BinaryExpression", + "start": 966, + "end": 1064, + "loc": { + "start": { + "line": 24, + "column": 2 + }, + "end": { + "line": 25, + "column": 88 + } + }, + "left": { + "type": "BinaryExpression", + "start": 967, + "end": 972, + "loc": { + "start": { + "line": 24, + "column": 3 + }, + "end": { + "line": 24, + "column": 8 + } + }, + "left": { + "type": "Identifier", + "start": 967, + "end": 968, + "loc": { + "start": { + "line": 24, + "column": 3 + }, + "end": { + "line": 24, + "column": 4 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 971, + "end": 972, + "loc": { + "start": { + "line": 24, + "column": 7 + }, + "end": { + "line": 24, + "column": 8 + } + }, + "name": "y" + } + }, + "operator": ">", + "right": { + "type": "ObjectExpression", + "start": 978, + "end": 1064, + "loc": { + "start": { + "line": 25, + "column": 2 + }, + "end": { + "line": 25, + "column": 88 + } + }, + "properties": [ + { + "type": "Property", + "start": 980, + "end": 1020, + "loc": { + "start": { + "line": 25, + "column": 4 + }, + "end": { + "line": 25, + "column": 44 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 980, + "end": 1017, + "loc": { + "start": { + "line": 25, + "column": 4 + }, + "end": { + "line": 25, + "column": 41 + } + }, + "name": "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" + }, + "value": { + "type": "Literal", + "start": 1019, + "end": 1020, + "loc": { + "start": { + "line": 25, + "column": 43 + }, + "end": { + "line": 25, + "column": 44 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + }, + { + "type": "Property", + "start": 1022, + "end": 1062, + "loc": { + "start": { + "line": 25, + "column": 46 + }, + "end": { + "line": 25, + "column": 86 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 1022, + "end": 1059, + "loc": { + "start": { + "line": 25, + "column": 46 + }, + "end": { + "line": 25, + "column": 83 + } + }, + "name": "lllllllllllllllllllllllllllllllllllll" + }, + "value": { + "type": "Literal", + "start": 1061, + "end": 1062, + "loc": { + "start": { + "line": 25, + "column": 85 + }, + "end": { + "line": 25, + "column": 86 + } + }, + "value": 2, + "raw": "2" + }, + "kind": "init" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " One character longer in the first key than `c2`: with the pair, the welded form no", + "start": 782, + "end": 867 + }, + { + "type": "Line", + "value": " longer fits, so the object drops to its own line — the break the pair survives.", + "start": 869, + "end": 951 + } + ] + } + ], + "sourceType": "module" + }, + "attributes": [ + { + "type": "Attribute", + "start": 8, + "end": 17, + "name": "lang", + "name_loc": { + "start": { + "line": 1, + "column": 8, + "character": 8 + }, + "end": { + "line": 1, + "column": 12, + "character": 12 + } + }, + "value": [ + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "ts", + "data": "ts" + } + ] + } + ] + } +} diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/input.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/input.svelte new file mode 100644 index 000000000..16265daa6 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/input.svelte @@ -0,0 +1,26 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/output_prettier.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/output_prettier.svelte new file mode 100644 index 000000000..8906da6f0 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_object_long_prettier_divergence/output_prettier.svelte @@ -0,0 +1,26 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/README.md b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/README.md new file mode 100644 index 000000000..caa115297 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/README.md @@ -0,0 +1,30 @@ +# relational_chain_type_arg_parens_prettier_divergence + +Prettier prints a relational chain bare wherever the author's own line break was the only thing keeping the `<`…`>` region out of a type-argument list; tsv keeps a paren pair around the `<` operand. + +tsv: `(fn < A[T]) > (t, u)` +Prettier: `fn < A[T] > (t, u)`, which its own second pass writes out as `fn(t, u)` + +## Reason + +**Semantic preservation.** `fn(t, u)` is a comparison chain to tsv, acorn-typescript and tsc alike: a line break before a `[` ends the type in both parsers (the loop in each is named in the catalog entry linked below), so the newline holds `[T]` to an index expression and the speculative type-argument parse fails. Every parse-then-format entry point folds that newline to nothing before it parses, so the break is gone from the output — and `fn < A[T] > (t, u)` re-parses as a `CallExpression` carrying a `TSTypeParameterInstantiation`. That is a different program, and prettier's second pass prints it as one (`fn(t, u)`, pinned by `audit_signature.txt`). tsv puts a pair around the `>`'s left operand instead — the same tree in the spelling every parser reads alike — and both synthesizes and retains it. + +The tail past the would-be closing `>` is not the axis: a sequence (`(t, u)`), a tagged template (`` `x` ``) and a lone arrow argument (`((t) => t)`) re-lex identically, because those followers commit a type-argument list on any line (which followers commit, for which parser, is stated in the catalog entry linked below). Neither is the callee shape — a bare name, a member and a `this` member ask the same question of the same join. + +The rule is **region-keyed**, not shape-keyed, so a `<` operand that is no type keeps the chain bare: `x < 1 + 2 > (t, u)`, `x < this.a > (t, u)` and `p < string$ ? q : r > (t, u)` are pinned from the bare side here and by [less_than_keyword_follow](../../../syntax/disambiguation/less_than_keyword_follow/) and [less_than_keyword_boundary](../../../syntax/disambiguation/less_than_keyword_boundary/). It is also **layout-blind** — whether the `>` ends a line is not knowable where parens are decided — so the pair stands at every width; the width-driven half of the same bug lives in [relational_chain_type_arg_parens_long](../relational_chain_type_arg_parens_long_prettier_divergence/) and the object-operand half in [relational_chain_type_arg_parens_object_long](../relational_chain_type_arg_parens_object_long_prettier_divergence/). + +## What "region-keyed" grades + +The **head** decides. A `{` or `[` head opens the region whatever its body holds, so `c1`–`c6` all take the pair — `[1, 2]`, `{ x: B }`, `{ [k]: 1 }` and `[...s]` because a tuple, a type literal, a computed key and a rest element are types to every parser, and `{ ...s }` and `[b, c++]` because the region is a type-argument list to a parser that grades no BODY. tsv's own is one: its bracketed head arms commit on any matching `>` that a line terminator, a `(` or a template follows, so it reads `x < { ...s } >⏎c` and `x < { ...s } > (c, d)` as type-argument lists and then rejects both, where acorn and tsc both read the comparison chain. A bare output would be one tsv cannot reparse, which is why the pair stands on the value bodies too. (The over-rejection itself is the parser's, not the formatter's.) + +A **paren shell is not part of the head at all** — the printer strips it — so the head question is asked of the shell's content: `b4`–`b6` are graded as the call and the function and class expressions their own paren-free twins are, and `(a < (b)!) > c` / `(a < ([1, 2])) > c` in `unformatted_ours_operand_shell` reach `input.svelte` from the shell-bearing side. A non-null `!` does open a region, prefix and postfix and through a member or an index (`c8`–`c12`): `T!` is tsc's `JSDocNonNullableType`, so `a < b! >⏎c` is an instantiation plus a statement to the compiler, where acorn-typescript — and so tsv's own parse — reads the comparison chain the flat line is. tsv follows acorn when it parses and, when it decides what its own OUTPUT will mean, the widest reading of every parser that will read it. + +One head class is deliberately absent, and it bounds the shell rule: an operand whose shell the printer **KEEPS**. Looking through the shell grades the stripped form, but the printed form still carries the `(` — so the relaxed reading answers about the content while the parse that reads the output answers about a `(`-headed region, which commits on any matching `>` that a line terminator, a `(` or a template follows, and then rejects the non-type body. The class is every operand whose shell survives printing and whose content is no type: assignment and compound assignment, a conditional, `||` / `&&` / `??`, equality, `^`, `in` / `instanceof`, `await`, `yield`, `as` / `satisfies`. (A kept shell whose content happens to SPELL a type is not in it — a sequence spells the argument separator, `&` and `|` a type intersection or union, and `() =>` a function type — so there the pair stands.) The failure is not an over-rejection of something an author wrote: it is **tsv's own output**, and two things reach it. A follower that commits with no break at all is one — `(x < (a = b)) > (c, d)` prints as `x < (a = b) > (c, d)` on one line, and a template or an arrow-in-parens follower does the same — and a width at which the `>` ends a line is the other, whatever the follower (`x < (a = b) > c` is harmless only while it fits). The underlying defect is the PARSER's, in the same head arm the tuple and type-literal ones live in, and until it is fixed a cell here would pin an output tsv cannot reparse. + +## Variants + +`unformatted_ours_region_break` carries the authored spelling the divergence is about — the `[` on its own line, in the escaped-identifier (`[\u{54}]`) and leading-dot (`[.5]`) spellings beside the plain one, since a type-argument head reads an escape and a `.`-led numeric as an ordinary identifier and literal. tsv normalizes it to `input.svelte`; prettier lands on the instantiation instead. + +`unformatted_ours_operand_shell` puts a redundant paren shell around the `<` operand of the cells whose verdict a shell must not move — `(a < ([1, 2])) > c`, `(a < ({ ...s })) > c`, `(a < (b)!) > c`, `x < (f()) > c` — the authoring direction `deno task paren:audit`'s `< > operand` class enumerates. Prettier drops tsv's pair as it does everywhere here, so only tsv normalizes it back to `input.svelte`. The bare-side twin of the same claim is `unformatted_operand_shell` in [relational_lt_vs_type_args](../relational_lt_vs_type_args/), where both formatters land on the input. + +See [conformance_prettier.md](../../../../../../docs/conformance_prettier.md) §Prettier bug index and [conformance_prettier_ts.md](../../../../../../docs/conformance_prettier_ts.md) §TypeScript (Relational chain type-argument parens). diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/audit_signature.txt b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/audit_signature.txt new file mode 100644 index 000000000..d73fd0af1 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/audit_signature.txt @@ -0,0 +1,63 @@ +# Auto-generated prettier chain signature. Do not edit manually. +# Regenerate: deno task fixtures:update:formatted +# +# Each %%PASS=N%% section is exactly prettier^N(output_prettier.). +# This file exists when prettier is non-idempotent on output_prettier.* — it pins +# the full chain so the audit recognizes the case and the validator catches drift. +# See docs/fixture_overview.md (rule F4) and crates/tsv_debug/src/fixtures/audit_signature.rs. + +%%PASS=2 (fixed point)%% + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/expected.json b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/expected.json new file mode 100644 index 000000000..55d83da0e --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/expected.json @@ -0,0 +1,4806 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 2367, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " A relational chain keeps a paren pair around its `<` operand whenever the region", + "start": 20, + "end": 103, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 84 + } + } + }, + { + "type": "Line", + "value": " between the `<` and the `>` would parse as a type-argument list. Bare, the printed", + "start": 105, + "end": 190, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 86 + } + } + }, + { + "type": "Line", + "value": " chain re-lexes as a call with type arguments — a different program — because the", + "start": 192, + "end": 275, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 4, + "column": 84 + } + } + }, + { + "type": "Line", + "value": " author's line break before the `[` is the only thing holding the index to an", + "start": 277, + "end": 356, + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 80 + } + } + }, + { + "type": "Line", + "value": " expression, and the formatter folds that break away.", + "start": 358, + "end": 413, + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 56 + } + } + }, + { + "type": "Line", + "value": " The tail past the would-be closing `>` is not the axis: a sequence, a tagged", + "start": 486, + "end": 565, + "loc": { + "start": { + "line": 10, + "column": 1 + }, + "end": { + "line": 10, + "column": 80 + } + } + }, + { + "type": "Line", + "value": " template, and a lone arrow argument all re-lex alike.", + "start": 567, + "end": 623, + "loc": { + "start": { + "line": 11, + "column": 1 + }, + "end": { + "line": 11, + "column": 57 + } + } + }, + { + "type": "Line", + "value": " Neither is the callee shape — a member and a `this` member ask the same question.", + "start": 695, + "end": 779, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 15, + "column": 85 + } + } + }, + { + "type": "Line", + "value": " A `{` or `[` head opens the region whatever its body holds, so the pair stands on", + "start": 855, + "end": 939, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 85 + } + } + }, + { + "type": "Line", + "value": " every one. A tuple, a type literal and a computed key ARE types, and a rest element", + "start": 941, + "end": 1027, + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 20, + "column": 87 + } + } + }, + { + "type": "Line", + "value": " is a tuple's own; an object spread and an update expression are not, and tsc reads", + "start": 1029, + "end": 1114, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 86 + } + } + }, + { + "type": "Line", + "value": " those two as the chain they are — but the same bytes are a type-argument list to a", + "start": 1116, + "end": 1201, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 22, + "column": 86 + } + } + }, + { + "type": "Line", + "value": " parser that grades no body, which is what tsv's own is here, so a bare output would", + "start": 1203, + "end": 1289, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 23, + "column": 87 + } + } + }, + { + "type": "Line", + "value": " be one tsv cannot reparse.", + "start": 1291, + "end": 1320, + "loc": { + "start": { + "line": 24, + "column": 1 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + { + "type": "Line", + "value": " A parenthesized type is a head too, and its own shell survives only where", + "start": 1513, + "end": 1589, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 32, + "column": 77 + } + } + }, + { + "type": "Line", + "value": " precedence needs it.", + "start": 1591, + "end": 1614, + "loc": { + "start": { + "line": 33, + "column": 1 + }, + "end": { + "line": 33, + "column": 24 + } + } + }, + { + "type": "Line", + "value": " A non-null `!` is a type to tsc (`JSDocNonNullableType`), prefix and postfix, and", + "start": 1648, + "end": 1732, + "loc": { + "start": { + "line": 36, + "column": 1 + }, + "end": { + "line": 36, + "column": 85 + } + } + }, + { + "type": "Line", + "value": " reads the same through a member, an index, and a shell the printer strips.", + "start": 1734, + "end": 1811, + "loc": { + "start": { + "line": 37, + "column": 1 + }, + "end": { + "line": 37, + "column": 78 + } + } + }, + { + "type": "Line", + "value": " An operand that is no type keeps the chain bare: arithmetic, a `this` member, and", + "start": 1953, + "end": 2037, + "loc": { + "start": { + "line": 44, + "column": 1 + }, + "end": { + "line": 44, + "column": 85 + } + } + }, + { + "type": "Line", + "value": " a name that merely begins with a type keyword.", + "start": 2039, + "end": 2088, + "loc": { + "start": { + "line": 45, + "column": 1 + }, + "end": { + "line": 45, + "column": 50 + } + } + }, + { + "type": "Line", + "value": " A call, and a function or class expression, are no types either.", + "start": 2198, + "end": 2265, + "loc": { + "start": { + "line": 50, + "column": 1 + }, + "end": { + "line": 50, + "column": 68 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 2366, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 2357, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 54, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 415, + "end": 447, + "loc": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 7, + "column": 33 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 421, + "end": 446, + "loc": { + "start": { + "line": 7, + "column": 7 + }, + "end": { + "line": 7, + "column": 32 + } + }, + "id": { + "type": "Identifier", + "start": 421, + "end": 423, + "loc": { + "start": { + "line": 7, + "column": 7 + }, + "end": { + "line": 7, + "column": 9 + } + }, + "name": "a1" + }, + "init": { + "type": "BinaryExpression", + "start": 426, + "end": 446, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 7, + "column": 32 + } + }, + "left": { + "type": "BinaryExpression", + "start": 427, + "end": 436, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 427, + "end": 429, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "name": "fn" + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 432, + "end": 436, + "loc": { + "start": { + "line": 7, + "column": 18 + }, + "end": { + "line": 7, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 432, + "end": 433, + "loc": { + "start": { + "line": 7, + "column": 18 + }, + "end": { + "line": 7, + "column": 19 + } + }, + "name": "A" + }, + "property": { + "type": "Identifier", + "start": 434, + "end": 435, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 21 + } + }, + "name": "T" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 441, + "end": 445, + "loc": { + "start": { + "line": 7, + "column": 27 + }, + "end": { + "line": 7, + "column": 31 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 441, + "end": 442, + "loc": { + "start": { + "line": 7, + "column": 27 + }, + "end": { + "line": 7, + "column": 28 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 444, + "end": 445, + "loc": { + "start": { + "line": 7, + "column": 30 + }, + "end": { + "line": 7, + "column": 31 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A relational chain keeps a paren pair around its `<` operand whenever the region", + "start": 20, + "end": 103 + }, + { + "type": "Line", + "value": " between the `<` and the `>` would parse as a type-argument list. Bare, the printed", + "start": 105, + "end": 190 + }, + { + "type": "Line", + "value": " chain re-lexes as a call with type arguments — a different program — because the", + "start": 192, + "end": 275 + }, + { + "type": "Line", + "value": " author's line break before the `[` is the only thing holding the index to an", + "start": 277, + "end": 356 + }, + { + "type": "Line", + "value": " expression, and the formatter folds that break away.", + "start": 358, + "end": 413 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 449, + "end": 483, + "loc": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 8, + "column": 35 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 455, + "end": 482, + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 34 + } + }, + "id": { + "type": "Identifier", + "start": 455, + "end": 457, + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 9 + } + }, + "name": "a2" + }, + "init": { + "type": "BinaryExpression", + "start": 460, + "end": 482, + "loc": { + "start": { + "line": 8, + "column": 12 + }, + "end": { + "line": 8, + "column": 34 + } + }, + "left": { + "type": "BinaryExpression", + "start": 461, + "end": 472, + "loc": { + "start": { + "line": 8, + "column": 13 + }, + "end": { + "line": 8, + "column": 24 + } + }, + "left": { + "type": "Identifier", + "start": 461, + "end": 463, + "loc": { + "start": { + "line": 8, + "column": 13 + }, + "end": { + "line": 8, + "column": 15 + } + }, + "name": "fn" + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 466, + "end": 472, + "loc": { + "start": { + "line": 8, + "column": 18 + }, + "end": { + "line": 8, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 466, + "end": 467, + "loc": { + "start": { + "line": 8, + "column": 18 + }, + "end": { + "line": 8, + "column": 19 + } + }, + "name": "A" + }, + "property": { + "type": "Literal", + "start": 468, + "end": 471, + "loc": { + "start": { + "line": 8, + "column": 20 + }, + "end": { + "line": 8, + "column": 23 + } + }, + "value": 0.5, + "raw": "0.5" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 477, + "end": 481, + "loc": { + "start": { + "line": 8, + "column": 29 + }, + "end": { + "line": 8, + "column": 33 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 477, + "end": 478, + "loc": { + "start": { + "line": 8, + "column": 29 + }, + "end": { + "line": 8, + "column": 30 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 480, + "end": 481, + "loc": { + "start": { + "line": 8, + "column": 32 + }, + "end": { + "line": 8, + "column": 33 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 625, + "end": 654, + "loc": { + "start": { + "line": 12, + "column": 1 + }, + "end": { + "line": 12, + "column": 30 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 631, + "end": 653, + "loc": { + "start": { + "line": 12, + "column": 7 + }, + "end": { + "line": 12, + "column": 29 + } + }, + "id": { + "type": "Identifier", + "start": 631, + "end": 633, + "loc": { + "start": { + "line": 12, + "column": 7 + }, + "end": { + "line": 12, + "column": 9 + } + }, + "name": "a3" + }, + "init": { + "type": "BinaryExpression", + "start": 636, + "end": 653, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 12, + "column": 29 + } + }, + "left": { + "type": "BinaryExpression", + "start": 637, + "end": 646, + "loc": { + "start": { + "line": 12, + "column": 13 + }, + "end": { + "line": 12, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 637, + "end": 639, + "loc": { + "start": { + "line": 12, + "column": 13 + }, + "end": { + "line": 12, + "column": 15 + } + }, + "name": "fn" + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 642, + "end": 646, + "loc": { + "start": { + "line": 12, + "column": 18 + }, + "end": { + "line": 12, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 642, + "end": 643, + "loc": { + "start": { + "line": 12, + "column": 18 + }, + "end": { + "line": 12, + "column": 19 + } + }, + "name": "A" + }, + "property": { + "type": "Identifier", + "start": 644, + "end": 645, + "loc": { + "start": { + "line": 12, + "column": 20 + }, + "end": { + "line": 12, + "column": 21 + } + }, + "name": "T" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "TemplateLiteral", + "start": 650, + "end": 653, + "loc": { + "start": { + "line": 12, + "column": 26 + }, + "end": { + "line": 12, + "column": 29 + } + }, + "expressions": [], + "quasis": [ + { + "type": "TemplateElement", + "start": 651, + "end": 652, + "loc": { + "start": { + "line": 12, + "column": 27 + }, + "end": { + "line": 12, + "column": 28 + } + }, + "value": { + "raw": "x", + "cooked": "x" + }, + "tail": true + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " The tail past the would-be closing `>` is not the axis: a sequence, a tagged", + "start": 486, + "end": 565 + }, + { + "type": "Line", + "value": " template, and a lone arrow argument all re-lex alike.", + "start": 567, + "end": 623 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 656, + "end": 692, + "loc": { + "start": { + "line": 13, + "column": 1 + }, + "end": { + "line": 13, + "column": 37 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 662, + "end": 691, + "loc": { + "start": { + "line": 13, + "column": 7 + }, + "end": { + "line": 13, + "column": 36 + } + }, + "id": { + "type": "Identifier", + "start": 662, + "end": 664, + "loc": { + "start": { + "line": 13, + "column": 7 + }, + "end": { + "line": 13, + "column": 9 + } + }, + "name": "a4" + }, + "init": { + "type": "BinaryExpression", + "start": 667, + "end": 691, + "loc": { + "start": { + "line": 13, + "column": 12 + }, + "end": { + "line": 13, + "column": 36 + } + }, + "left": { + "type": "BinaryExpression", + "start": 668, + "end": 677, + "loc": { + "start": { + "line": 13, + "column": 13 + }, + "end": { + "line": 13, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 668, + "end": 670, + "loc": { + "start": { + "line": 13, + "column": 13 + }, + "end": { + "line": 13, + "column": 15 + } + }, + "name": "fn" + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 673, + "end": 677, + "loc": { + "start": { + "line": 13, + "column": 18 + }, + "end": { + "line": 13, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 673, + "end": 674, + "loc": { + "start": { + "line": 13, + "column": 18 + }, + "end": { + "line": 13, + "column": 19 + } + }, + "name": "A" + }, + "property": { + "type": "Identifier", + "start": 675, + "end": 676, + "loc": { + "start": { + "line": 13, + "column": 20 + }, + "end": { + "line": 13, + "column": 21 + } + }, + "name": "T" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "ArrowFunctionExpression", + "start": 682, + "end": 690, + "loc": { + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 13, + "column": 35 + } + }, + "id": null, + "expression": true, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 683, + "end": 684, + "loc": { + "start": { + "line": 13, + "column": 28 + }, + "end": { + "line": 13, + "column": 29 + } + }, + "name": "t" + } + ], + "body": { + "type": "Identifier", + "start": 689, + "end": 690, + "loc": { + "start": { + "line": 13, + "column": 34 + }, + "end": { + "line": 13, + "column": 35 + } + }, + "name": "t" + } + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 781, + "end": 814, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 16, + "column": 34 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 787, + "end": 813, + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 33 + } + }, + "id": { + "type": "Identifier", + "start": 787, + "end": 789, + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 9 + } + }, + "name": "a5" + }, + "init": { + "type": "BinaryExpression", + "start": 792, + "end": 813, + "loc": { + "start": { + "line": 16, + "column": 12 + }, + "end": { + "line": 16, + "column": 33 + } + }, + "left": { + "type": "BinaryExpression", + "start": 793, + "end": 803, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 23 + } + }, + "left": { + "type": "MemberExpression", + "start": 793, + "end": 796, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 16 + } + }, + "object": { + "type": "Identifier", + "start": 793, + "end": 794, + "loc": { + "start": { + "line": 16, + "column": 13 + }, + "end": { + "line": 16, + "column": 14 + } + }, + "name": "a" + }, + "property": { + "type": "Identifier", + "start": 795, + "end": 796, + "loc": { + "start": { + "line": 16, + "column": 15 + }, + "end": { + "line": 16, + "column": 16 + } + }, + "name": "b" + }, + "computed": false, + "optional": false + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 799, + "end": 803, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 799, + "end": 800, + "loc": { + "start": { + "line": 16, + "column": 19 + }, + "end": { + "line": 16, + "column": 20 + } + }, + "name": "A" + }, + "property": { + "type": "Identifier", + "start": 801, + "end": 802, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 22 + } + }, + "name": "T" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 808, + "end": 812, + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 32 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 808, + "end": 809, + "loc": { + "start": { + "line": 16, + "column": 28 + }, + "end": { + "line": 16, + "column": 29 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 811, + "end": 812, + "loc": { + "start": { + "line": 16, + "column": 31 + }, + "end": { + "line": 16, + "column": 32 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " Neither is the callee shape — a member and a `this` member ask the same question.", + "start": 695, + "end": 779 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 816, + "end": 852, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 37 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 822, + "end": 851, + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 36 + } + }, + "id": { + "type": "Identifier", + "start": 822, + "end": 824, + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 9 + } + }, + "name": "a6" + }, + "init": { + "type": "BinaryExpression", + "start": 827, + "end": 851, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 36 + } + }, + "left": { + "type": "BinaryExpression", + "start": 828, + "end": 841, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 26 + } + }, + "left": { + "type": "MemberExpression", + "start": 828, + "end": 834, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 19 + } + }, + "object": { + "type": "ThisExpression", + "start": 828, + "end": 832, + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + "property": { + "type": "Identifier", + "start": 833, + "end": 834, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 19 + } + }, + "name": "b" + }, + "computed": false, + "optional": false + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 837, + "end": 841, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 26 + } + }, + "object": { + "type": "Identifier", + "start": 837, + "end": 838, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 17, + "column": 23 + } + }, + "name": "A" + }, + "property": { + "type": "Identifier", + "start": 839, + "end": 840, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 25 + } + }, + "name": "T" + }, + "computed": true, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 846, + "end": 850, + "loc": { + "start": { + "line": 17, + "column": 31 + }, + "end": { + "line": 17, + "column": 35 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 846, + "end": 847, + "loc": { + "start": { + "line": 17, + "column": 31 + }, + "end": { + "line": 17, + "column": 32 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 849, + "end": 850, + "loc": { + "start": { + "line": 17, + "column": 34 + }, + "end": { + "line": 17, + "column": 35 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1322, + "end": 1350, + "loc": { + "start": { + "line": 25, + "column": 1 + }, + "end": { + "line": 25, + "column": 29 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1328, + "end": 1349, + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 28 + } + }, + "id": { + "type": "Identifier", + "start": 1328, + "end": 1330, + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 9 + } + }, + "name": "c1" + }, + "init": { + "type": "BinaryExpression", + "start": 1333, + "end": 1349, + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 28 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1334, + "end": 1344, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 1334, + "end": 1335, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ArrayExpression", + "start": 1338, + "end": 1344, + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 23 + } + }, + "elements": [ + { + "type": "Literal", + "start": 1339, + "end": 1340, + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 19 + } + }, + "value": 1, + "raw": "1" + }, + { + "type": "Literal", + "start": 1342, + "end": 1343, + "loc": { + "start": { + "line": 25, + "column": 21 + }, + "end": { + "line": 25, + "column": 22 + } + }, + "value": 2, + "raw": "2" + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1348, + "end": 1349, + "loc": { + "start": { + "line": 25, + "column": 27 + }, + "end": { + "line": 25, + "column": 28 + } + }, + "name": "c" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A `{` or `[` head opens the region whatever its body holds, so the pair stands on", + "start": 855, + "end": 939 + }, + { + "type": "Line", + "value": " every one. A tuple, a type literal and a computed key ARE types, and a rest element", + "start": 941, + "end": 1027 + }, + { + "type": "Line", + "value": " is a tuple's own; an object spread and an update expression are not, and tsc reads", + "start": 1029, + "end": 1114 + }, + { + "type": "Line", + "value": " those two as the chain they are — but the same bytes are a type-argument list to a", + "start": 1116, + "end": 1201 + }, + { + "type": "Line", + "value": " parser that grades no body, which is what tsv's own is here, so a bare output would", + "start": 1203, + "end": 1289 + }, + { + "type": "Line", + "value": " be one tsv cannot reparse.", + "start": 1291, + "end": 1320 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1352, + "end": 1382, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 26, + "column": 31 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1358, + "end": 1381, + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 30 + } + }, + "id": { + "type": "Identifier", + "start": 1358, + "end": 1360, + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 9 + } + }, + "name": "c2" + }, + "init": { + "type": "BinaryExpression", + "start": 1363, + "end": 1381, + "loc": { + "start": { + "line": 26, + "column": 12 + }, + "end": { + "line": 26, + "column": 30 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1364, + "end": 1376, + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 25 + } + }, + "left": { + "type": "Identifier", + "start": 1364, + "end": 1365, + "loc": { + "start": { + "line": 26, + "column": 13 + }, + "end": { + "line": 26, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ObjectExpression", + "start": 1368, + "end": 1376, + "loc": { + "start": { + "line": 26, + "column": 17 + }, + "end": { + "line": 26, + "column": 25 + } + }, + "properties": [ + { + "type": "Property", + "start": 1370, + "end": 1374, + "loc": { + "start": { + "line": 26, + "column": 19 + }, + "end": { + "line": 26, + "column": 23 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 1370, + "end": 1371, + "loc": { + "start": { + "line": 26, + "column": 19 + }, + "end": { + "line": 26, + "column": 20 + } + }, + "name": "x" + }, + "value": { + "type": "Identifier", + "start": 1373, + "end": 1374, + "loc": { + "start": { + "line": 26, + "column": 22 + }, + "end": { + "line": 26, + "column": 23 + } + }, + "name": "B" + }, + "kind": "init" + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1380, + "end": 1381, + "loc": { + "start": { + "line": 26, + "column": 29 + }, + "end": { + "line": 26, + "column": 30 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1384, + "end": 1416, + "loc": { + "start": { + "line": 27, + "column": 1 + }, + "end": { + "line": 27, + "column": 33 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1390, + "end": 1415, + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 32 + } + }, + "id": { + "type": "Identifier", + "start": 1390, + "end": 1392, + "loc": { + "start": { + "line": 27, + "column": 7 + }, + "end": { + "line": 27, + "column": 9 + } + }, + "name": "c3" + }, + "init": { + "type": "BinaryExpression", + "start": 1395, + "end": 1415, + "loc": { + "start": { + "line": 27, + "column": 12 + }, + "end": { + "line": 27, + "column": 32 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1396, + "end": 1410, + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 27 + } + }, + "left": { + "type": "Identifier", + "start": 1396, + "end": 1397, + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ObjectExpression", + "start": 1400, + "end": 1410, + "loc": { + "start": { + "line": 27, + "column": 17 + }, + "end": { + "line": 27, + "column": 27 + } + }, + "properties": [ + { + "type": "Property", + "start": 1402, + "end": 1408, + "loc": { + "start": { + "line": 27, + "column": 19 + }, + "end": { + "line": 27, + "column": 25 + } + }, + "method": false, + "shorthand": false, + "computed": true, + "key": { + "type": "Identifier", + "start": 1403, + "end": 1404, + "loc": { + "start": { + "line": 27, + "column": 20 + }, + "end": { + "line": 27, + "column": 21 + } + }, + "name": "k" + }, + "value": { + "type": "Literal", + "start": 1407, + "end": 1408, + "loc": { + "start": { + "line": 27, + "column": 24 + }, + "end": { + "line": 27, + "column": 25 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1414, + "end": 1415, + "loc": { + "start": { + "line": 27, + "column": 31 + }, + "end": { + "line": 27, + "column": 32 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1418, + "end": 1446, + "loc": { + "start": { + "line": 28, + "column": 1 + }, + "end": { + "line": 28, + "column": 29 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1424, + "end": 1445, + "loc": { + "start": { + "line": 28, + "column": 7 + }, + "end": { + "line": 28, + "column": 28 + } + }, + "id": { + "type": "Identifier", + "start": 1424, + "end": 1426, + "loc": { + "start": { + "line": 28, + "column": 7 + }, + "end": { + "line": 28, + "column": 9 + } + }, + "name": "c4" + }, + "init": { + "type": "BinaryExpression", + "start": 1429, + "end": 1445, + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 28 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1430, + "end": 1440, + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 1430, + "end": 1431, + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ArrayExpression", + "start": 1434, + "end": 1440, + "loc": { + "start": { + "line": 28, + "column": 17 + }, + "end": { + "line": 28, + "column": 23 + } + }, + "elements": [ + { + "type": "SpreadElement", + "start": 1435, + "end": 1439, + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 22 + } + }, + "argument": { + "type": "Identifier", + "start": 1438, + "end": 1439, + "loc": { + "start": { + "line": 28, + "column": 21 + }, + "end": { + "line": 28, + "column": 22 + } + }, + "name": "s" + } + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1444, + "end": 1445, + "loc": { + "start": { + "line": 28, + "column": 27 + }, + "end": { + "line": 28, + "column": 28 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1448, + "end": 1478, + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 29, + "column": 31 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1454, + "end": 1477, + "loc": { + "start": { + "line": 29, + "column": 7 + }, + "end": { + "line": 29, + "column": 30 + } + }, + "id": { + "type": "Identifier", + "start": 1454, + "end": 1456, + "loc": { + "start": { + "line": 29, + "column": 7 + }, + "end": { + "line": 29, + "column": 9 + } + }, + "name": "c5" + }, + "init": { + "type": "BinaryExpression", + "start": 1459, + "end": 1477, + "loc": { + "start": { + "line": 29, + "column": 12 + }, + "end": { + "line": 29, + "column": 30 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1460, + "end": 1472, + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 29, + "column": 25 + } + }, + "left": { + "type": "Identifier", + "start": 1460, + "end": 1461, + "loc": { + "start": { + "line": 29, + "column": 13 + }, + "end": { + "line": 29, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ObjectExpression", + "start": 1464, + "end": 1472, + "loc": { + "start": { + "line": 29, + "column": 17 + }, + "end": { + "line": 29, + "column": 25 + } + }, + "properties": [ + { + "type": "SpreadElement", + "start": 1466, + "end": 1470, + "loc": { + "start": { + "line": 29, + "column": 19 + }, + "end": { + "line": 29, + "column": 23 + } + }, + "argument": { + "type": "Identifier", + "start": 1469, + "end": 1470, + "loc": { + "start": { + "line": 29, + "column": 22 + }, + "end": { + "line": 29, + "column": 23 + } + }, + "name": "s" + } + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1476, + "end": 1477, + "loc": { + "start": { + "line": 29, + "column": 29 + }, + "end": { + "line": 29, + "column": 30 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1480, + "end": 1510, + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 30, + "column": 31 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1486, + "end": 1509, + "loc": { + "start": { + "line": 30, + "column": 7 + }, + "end": { + "line": 30, + "column": 30 + } + }, + "id": { + "type": "Identifier", + "start": 1486, + "end": 1488, + "loc": { + "start": { + "line": 30, + "column": 7 + }, + "end": { + "line": 30, + "column": 9 + } + }, + "name": "c6" + }, + "init": { + "type": "BinaryExpression", + "start": 1491, + "end": 1509, + "loc": { + "start": { + "line": 30, + "column": 12 + }, + "end": { + "line": 30, + "column": 30 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1492, + "end": 1504, + "loc": { + "start": { + "line": 30, + "column": 13 + }, + "end": { + "line": 30, + "column": 25 + } + }, + "left": { + "type": "Identifier", + "start": 1492, + "end": 1493, + "loc": { + "start": { + "line": 30, + "column": 13 + }, + "end": { + "line": 30, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "ArrayExpression", + "start": 1496, + "end": 1504, + "loc": { + "start": { + "line": 30, + "column": 17 + }, + "end": { + "line": 30, + "column": 25 + } + }, + "elements": [ + { + "type": "Identifier", + "start": 1497, + "end": 1498, + "loc": { + "start": { + "line": 30, + "column": 18 + }, + "end": { + "line": 30, + "column": 19 + } + }, + "name": "b" + }, + { + "type": "UpdateExpression", + "start": 1500, + "end": 1503, + "loc": { + "start": { + "line": 30, + "column": 21 + }, + "end": { + "line": 30, + "column": 24 + } + }, + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "start": 1500, + "end": 1501, + "loc": { + "start": { + "line": 30, + "column": 21 + }, + "end": { + "line": 30, + "column": 22 + } + }, + "name": "c" + } + } + ] + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1508, + "end": 1509, + "loc": { + "start": { + "line": 30, + "column": 29 + }, + "end": { + "line": 30, + "column": 30 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1616, + "end": 1645, + "loc": { + "start": { + "line": 34, + "column": 1 + }, + "end": { + "line": 34, + "column": 30 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1622, + "end": 1644, + "loc": { + "start": { + "line": 34, + "column": 7 + }, + "end": { + "line": 34, + "column": 29 + } + }, + "id": { + "type": "Identifier", + "start": 1622, + "end": 1624, + "loc": { + "start": { + "line": 34, + "column": 7 + }, + "end": { + "line": 34, + "column": 9 + } + }, + "name": "c7" + }, + "init": { + "type": "BinaryExpression", + "start": 1627, + "end": 1644, + "loc": { + "start": { + "line": 34, + "column": 12 + }, + "end": { + "line": 34, + "column": 29 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1628, + "end": 1639, + "loc": { + "start": { + "line": 34, + "column": 13 + }, + "end": { + "line": 34, + "column": 24 + } + }, + "left": { + "type": "Identifier", + "start": 1628, + "end": 1629, + "loc": { + "start": { + "line": 34, + "column": 13 + }, + "end": { + "line": 34, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "BinaryExpression", + "start": 1633, + "end": 1638, + "loc": { + "start": { + "line": 34, + "column": 18 + }, + "end": { + "line": 34, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 1633, + "end": 1634, + "loc": { + "start": { + "line": 34, + "column": 18 + }, + "end": { + "line": 34, + "column": 19 + } + }, + "name": "A" + }, + "operator": "|", + "right": { + "type": "Identifier", + "start": 1637, + "end": 1638, + "loc": { + "start": { + "line": 34, + "column": 22 + }, + "end": { + "line": 34, + "column": 23 + } + }, + "name": "B" + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1643, + "end": 1644, + "loc": { + "start": { + "line": 34, + "column": 28 + }, + "end": { + "line": 34, + "column": 29 + } + }, + "name": "c" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A parenthesized type is a head too, and its own shell survives only where", + "start": 1513, + "end": 1589 + }, + { + "type": "Line", + "value": " precedence needs it.", + "start": 1591, + "end": 1614 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1813, + "end": 1837, + "loc": { + "start": { + "line": 38, + "column": 1 + }, + "end": { + "line": 38, + "column": 25 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1819, + "end": 1836, + "loc": { + "start": { + "line": 38, + "column": 7 + }, + "end": { + "line": 38, + "column": 24 + } + }, + "id": { + "type": "Identifier", + "start": 1819, + "end": 1821, + "loc": { + "start": { + "line": 38, + "column": 7 + }, + "end": { + "line": 38, + "column": 9 + } + }, + "name": "c8" + }, + "init": { + "type": "BinaryExpression", + "start": 1824, + "end": 1836, + "loc": { + "start": { + "line": 38, + "column": 12 + }, + "end": { + "line": 38, + "column": 24 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1825, + "end": 1831, + "loc": { + "start": { + "line": 38, + "column": 13 + }, + "end": { + "line": 38, + "column": 19 + } + }, + "left": { + "type": "Identifier", + "start": 1825, + "end": 1826, + "loc": { + "start": { + "line": 38, + "column": 13 + }, + "end": { + "line": 38, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "TSNonNullExpression", + "start": 1829, + "end": 1831, + "loc": { + "start": { + "line": 38, + "column": 17 + }, + "end": { + "line": 38, + "column": 19 + } + }, + "expression": { + "type": "Identifier", + "start": 1829, + "end": 1830, + "loc": { + "start": { + "line": 38, + "column": 17 + }, + "end": { + "line": 38, + "column": 18 + } + }, + "name": "b" + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1835, + "end": 1836, + "loc": { + "start": { + "line": 38, + "column": 23 + }, + "end": { + "line": 38, + "column": 24 + } + }, + "name": "c" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A non-null `!` is a type to tsc (`JSDocNonNullableType`), prefix and postfix, and", + "start": 1648, + "end": 1732 + }, + { + "type": "Line", + "value": " reads the same through a member, an index, and a shell the printer strips.", + "start": 1734, + "end": 1811 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1839, + "end": 1864, + "loc": { + "start": { + "line": 39, + "column": 1 + }, + "end": { + "line": 39, + "column": 26 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1845, + "end": 1863, + "loc": { + "start": { + "line": 39, + "column": 7 + }, + "end": { + "line": 39, + "column": 25 + } + }, + "id": { + "type": "Identifier", + "start": 1845, + "end": 1847, + "loc": { + "start": { + "line": 39, + "column": 7 + }, + "end": { + "line": 39, + "column": 9 + } + }, + "name": "c9" + }, + "init": { + "type": "BinaryExpression", + "start": 1850, + "end": 1863, + "loc": { + "start": { + "line": 39, + "column": 12 + }, + "end": { + "line": 39, + "column": 25 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1851, + "end": 1858, + "loc": { + "start": { + "line": 39, + "column": 13 + }, + "end": { + "line": 39, + "column": 20 + } + }, + "left": { + "type": "Identifier", + "start": 1851, + "end": 1852, + "loc": { + "start": { + "line": 39, + "column": 13 + }, + "end": { + "line": 39, + "column": 14 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "TSNonNullExpression", + "start": 1855, + "end": 1858, + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 20 + } + }, + "expression": { + "type": "TSNonNullExpression", + "start": 1855, + "end": 1857, + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 19 + } + }, + "expression": { + "type": "Identifier", + "start": 1855, + "end": 1856, + "loc": { + "start": { + "line": 39, + "column": 17 + }, + "end": { + "line": 39, + "column": 18 + } + }, + "name": "b" + } + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1862, + "end": 1863, + "loc": { + "start": { + "line": 39, + "column": 24 + }, + "end": { + "line": 39, + "column": 25 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1866, + "end": 1893, + "loc": { + "start": { + "line": 40, + "column": 1 + }, + "end": { + "line": 40, + "column": 28 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1872, + "end": 1892, + "loc": { + "start": { + "line": 40, + "column": 7 + }, + "end": { + "line": 40, + "column": 27 + } + }, + "id": { + "type": "Identifier", + "start": 1872, + "end": 1875, + "loc": { + "start": { + "line": 40, + "column": 7 + }, + "end": { + "line": 40, + "column": 10 + } + }, + "name": "c10" + }, + "init": { + "type": "BinaryExpression", + "start": 1878, + "end": 1892, + "loc": { + "start": { + "line": 40, + "column": 13 + }, + "end": { + "line": 40, + "column": 27 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1879, + "end": 1887, + "loc": { + "start": { + "line": 40, + "column": 14 + }, + "end": { + "line": 40, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 1879, + "end": 1880, + "loc": { + "start": { + "line": 40, + "column": 14 + }, + "end": { + "line": 40, + "column": 15 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "TSNonNullExpression", + "start": 1883, + "end": 1887, + "loc": { + "start": { + "line": 40, + "column": 18 + }, + "end": { + "line": 40, + "column": 22 + } + }, + "expression": { + "type": "MemberExpression", + "start": 1883, + "end": 1886, + "loc": { + "start": { + "line": 40, + "column": 18 + }, + "end": { + "line": 40, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 1883, + "end": 1884, + "loc": { + "start": { + "line": 40, + "column": 18 + }, + "end": { + "line": 40, + "column": 19 + } + }, + "name": "b" + }, + "property": { + "type": "Identifier", + "start": 1885, + "end": 1886, + "loc": { + "start": { + "line": 40, + "column": 20 + }, + "end": { + "line": 40, + "column": 21 + } + }, + "name": "c" + }, + "computed": false, + "optional": false + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1891, + "end": 1892, + "loc": { + "start": { + "line": 40, + "column": 26 + }, + "end": { + "line": 40, + "column": 27 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1895, + "end": 1923, + "loc": { + "start": { + "line": 41, + "column": 1 + }, + "end": { + "line": 41, + "column": 29 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1901, + "end": 1922, + "loc": { + "start": { + "line": 41, + "column": 7 + }, + "end": { + "line": 41, + "column": 28 + } + }, + "id": { + "type": "Identifier", + "start": 1901, + "end": 1904, + "loc": { + "start": { + "line": 41, + "column": 7 + }, + "end": { + "line": 41, + "column": 10 + } + }, + "name": "c11" + }, + "init": { + "type": "BinaryExpression", + "start": 1907, + "end": 1922, + "loc": { + "start": { + "line": 41, + "column": 13 + }, + "end": { + "line": 41, + "column": 28 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1908, + "end": 1917, + "loc": { + "start": { + "line": 41, + "column": 14 + }, + "end": { + "line": 41, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 1908, + "end": 1909, + "loc": { + "start": { + "line": 41, + "column": 14 + }, + "end": { + "line": 41, + "column": 15 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "TSNonNullExpression", + "start": 1912, + "end": 1917, + "loc": { + "start": { + "line": 41, + "column": 18 + }, + "end": { + "line": 41, + "column": 23 + } + }, + "expression": { + "type": "MemberExpression", + "start": 1912, + "end": 1916, + "loc": { + "start": { + "line": 41, + "column": 18 + }, + "end": { + "line": 41, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 1912, + "end": 1913, + "loc": { + "start": { + "line": 41, + "column": 18 + }, + "end": { + "line": 41, + "column": 19 + } + }, + "name": "B" + }, + "property": { + "type": "Identifier", + "start": 1914, + "end": 1915, + "loc": { + "start": { + "line": 41, + "column": 20 + }, + "end": { + "line": 41, + "column": 21 + } + }, + "name": "c" + }, + "computed": true, + "optional": false + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1921, + "end": 1922, + "loc": { + "start": { + "line": 41, + "column": 27 + }, + "end": { + "line": 41, + "column": 28 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 1925, + "end": 1950, + "loc": { + "start": { + "line": 42, + "column": 1 + }, + "end": { + "line": 42, + "column": 26 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1931, + "end": 1949, + "loc": { + "start": { + "line": 42, + "column": 7 + }, + "end": { + "line": 42, + "column": 25 + } + }, + "id": { + "type": "Identifier", + "start": 1931, + "end": 1934, + "loc": { + "start": { + "line": 42, + "column": 7 + }, + "end": { + "line": 42, + "column": 10 + } + }, + "name": "c12" + }, + "init": { + "type": "BinaryExpression", + "start": 1937, + "end": 1949, + "loc": { + "start": { + "line": 42, + "column": 13 + }, + "end": { + "line": 42, + "column": 25 + } + }, + "left": { + "type": "BinaryExpression", + "start": 1938, + "end": 1944, + "loc": { + "start": { + "line": 42, + "column": 14 + }, + "end": { + "line": 42, + "column": 20 + } + }, + "left": { + "type": "Identifier", + "start": 1938, + "end": 1939, + "loc": { + "start": { + "line": 42, + "column": 14 + }, + "end": { + "line": 42, + "column": 15 + } + }, + "name": "a" + }, + "operator": "<", + "right": { + "type": "UnaryExpression", + "start": 1942, + "end": 1944, + "loc": { + "start": { + "line": 42, + "column": 18 + }, + "end": { + "line": 42, + "column": 20 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 1943, + "end": 1944, + "loc": { + "start": { + "line": 42, + "column": 19 + }, + "end": { + "line": 42, + "column": 20 + } + }, + "name": "b" + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 1948, + "end": 1949, + "loc": { + "start": { + "line": 42, + "column": 24 + }, + "end": { + "line": 42, + "column": 25 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 2090, + "end": 2120, + "loc": { + "start": { + "line": 46, + "column": 1 + }, + "end": { + "line": 46, + "column": 31 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2096, + "end": 2119, + "loc": { + "start": { + "line": 46, + "column": 7 + }, + "end": { + "line": 46, + "column": 30 + } + }, + "id": { + "type": "Identifier", + "start": 2096, + "end": 2098, + "loc": { + "start": { + "line": 46, + "column": 7 + }, + "end": { + "line": 46, + "column": 9 + } + }, + "name": "b1" + }, + "init": { + "type": "BinaryExpression", + "start": 2101, + "end": 2119, + "loc": { + "start": { + "line": 46, + "column": 12 + }, + "end": { + "line": 46, + "column": 30 + } + }, + "left": { + "type": "BinaryExpression", + "start": 2101, + "end": 2110, + "loc": { + "start": { + "line": 46, + "column": 12 + }, + "end": { + "line": 46, + "column": 21 + } + }, + "left": { + "type": "Identifier", + "start": 2101, + "end": 2102, + "loc": { + "start": { + "line": 46, + "column": 12 + }, + "end": { + "line": 46, + "column": 13 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "BinaryExpression", + "start": 2105, + "end": 2110, + "loc": { + "start": { + "line": 46, + "column": 16 + }, + "end": { + "line": 46, + "column": 21 + } + }, + "left": { + "type": "Literal", + "start": 2105, + "end": 2106, + "loc": { + "start": { + "line": 46, + "column": 16 + }, + "end": { + "line": 46, + "column": 17 + } + }, + "value": 1, + "raw": "1" + }, + "operator": "+", + "right": { + "type": "Literal", + "start": 2109, + "end": 2110, + "loc": { + "start": { + "line": 46, + "column": 20 + }, + "end": { + "line": 46, + "column": 21 + } + }, + "value": 2, + "raw": "2" + } + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 2114, + "end": 2118, + "loc": { + "start": { + "line": 46, + "column": 25 + }, + "end": { + "line": 46, + "column": 29 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 2114, + "end": 2115, + "loc": { + "start": { + "line": 46, + "column": 25 + }, + "end": { + "line": 46, + "column": 26 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 2117, + "end": 2118, + "loc": { + "start": { + "line": 46, + "column": 28 + }, + "end": { + "line": 46, + "column": 29 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " An operand that is no type keeps the chain bare: arithmetic, a `this` member, and", + "start": 1953, + "end": 2037 + }, + { + "type": "Line", + "value": " a name that merely begins with a type keyword.", + "start": 2039, + "end": 2088 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 2122, + "end": 2153, + "loc": { + "start": { + "line": 47, + "column": 1 + }, + "end": { + "line": 47, + "column": 32 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2128, + "end": 2152, + "loc": { + "start": { + "line": 47, + "column": 7 + }, + "end": { + "line": 47, + "column": 31 + } + }, + "id": { + "type": "Identifier", + "start": 2128, + "end": 2130, + "loc": { + "start": { + "line": 47, + "column": 7 + }, + "end": { + "line": 47, + "column": 9 + } + }, + "name": "b2" + }, + "init": { + "type": "BinaryExpression", + "start": 2133, + "end": 2152, + "loc": { + "start": { + "line": 47, + "column": 12 + }, + "end": { + "line": 47, + "column": 31 + } + }, + "left": { + "type": "BinaryExpression", + "start": 2133, + "end": 2143, + "loc": { + "start": { + "line": 47, + "column": 12 + }, + "end": { + "line": 47, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 2133, + "end": 2134, + "loc": { + "start": { + "line": 47, + "column": 12 + }, + "end": { + "line": 47, + "column": 13 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "start": 2137, + "end": 2143, + "loc": { + "start": { + "line": 47, + "column": 16 + }, + "end": { + "line": 47, + "column": 22 + } + }, + "object": { + "type": "ThisExpression", + "start": 2137, + "end": 2141, + "loc": { + "start": { + "line": 47, + "column": 16 + }, + "end": { + "line": 47, + "column": 20 + } + } + }, + "property": { + "type": "Identifier", + "start": 2142, + "end": 2143, + "loc": { + "start": { + "line": 47, + "column": 21 + }, + "end": { + "line": 47, + "column": 22 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + } + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 2147, + "end": 2151, + "loc": { + "start": { + "line": 47, + "column": 26 + }, + "end": { + "line": 47, + "column": 30 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 2147, + "end": 2148, + "loc": { + "start": { + "line": 47, + "column": 26 + }, + "end": { + "line": 47, + "column": 27 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 2150, + "end": 2151, + "loc": { + "start": { + "line": 47, + "column": 29 + }, + "end": { + "line": 47, + "column": 30 + } + }, + "name": "u" + } + ] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 2155, + "end": 2195, + "loc": { + "start": { + "line": 48, + "column": 1 + }, + "end": { + "line": 48, + "column": 41 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2161, + "end": 2194, + "loc": { + "start": { + "line": 48, + "column": 7 + }, + "end": { + "line": 48, + "column": 40 + } + }, + "id": { + "type": "Identifier", + "start": 2161, + "end": 2163, + "loc": { + "start": { + "line": 48, + "column": 7 + }, + "end": { + "line": 48, + "column": 9 + } + }, + "name": "b3" + }, + "init": { + "type": "ConditionalExpression", + "start": 2166, + "end": 2194, + "loc": { + "start": { + "line": 48, + "column": 12 + }, + "end": { + "line": 48, + "column": 40 + } + }, + "test": { + "type": "BinaryExpression", + "start": 2166, + "end": 2177, + "loc": { + "start": { + "line": 48, + "column": 12 + }, + "end": { + "line": 48, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 2166, + "end": 2167, + "loc": { + "start": { + "line": 48, + "column": 12 + }, + "end": { + "line": 48, + "column": 13 + } + }, + "name": "p" + }, + "operator": "<", + "right": { + "type": "Identifier", + "start": 2170, + "end": 2177, + "loc": { + "start": { + "line": 48, + "column": 16 + }, + "end": { + "line": 48, + "column": 23 + } + }, + "name": "string$" + } + }, + "consequent": { + "type": "Identifier", + "start": 2180, + "end": 2181, + "loc": { + "start": { + "line": 48, + "column": 26 + }, + "end": { + "line": 48, + "column": 27 + } + }, + "name": "q" + }, + "alternate": { + "type": "BinaryExpression", + "start": 2184, + "end": 2194, + "loc": { + "start": { + "line": 48, + "column": 30 + }, + "end": { + "line": 48, + "column": 40 + } + }, + "left": { + "type": "Identifier", + "start": 2184, + "end": 2185, + "loc": { + "start": { + "line": 48, + "column": 30 + }, + "end": { + "line": 48, + "column": 31 + } + }, + "name": "r" + }, + "operator": ">", + "right": { + "type": "SequenceExpression", + "start": 2189, + "end": 2193, + "loc": { + "start": { + "line": 48, + "column": 35 + }, + "end": { + "line": 48, + "column": 39 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 2189, + "end": 2190, + "loc": { + "start": { + "line": 48, + "column": 35 + }, + "end": { + "line": 48, + "column": 36 + } + }, + "name": "t" + }, + { + "type": "Identifier", + "start": 2192, + "end": 2193, + "loc": { + "start": { + "line": 48, + "column": 38 + }, + "end": { + "line": 48, + "column": 39 + } + }, + "name": "u" + } + ] + } + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 2267, + "end": 2290, + "loc": { + "start": { + "line": 51, + "column": 1 + }, + "end": { + "line": 51, + "column": 24 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2273, + "end": 2289, + "loc": { + "start": { + "line": 51, + "column": 7 + }, + "end": { + "line": 51, + "column": 23 + } + }, + "id": { + "type": "Identifier", + "start": 2273, + "end": 2275, + "loc": { + "start": { + "line": 51, + "column": 7 + }, + "end": { + "line": 51, + "column": 9 + } + }, + "name": "b4" + }, + "init": { + "type": "BinaryExpression", + "start": 2278, + "end": 2289, + "loc": { + "start": { + "line": 51, + "column": 12 + }, + "end": { + "line": 51, + "column": 23 + } + }, + "left": { + "type": "BinaryExpression", + "start": 2278, + "end": 2285, + "loc": { + "start": { + "line": 51, + "column": 12 + }, + "end": { + "line": 51, + "column": 19 + } + }, + "left": { + "type": "Identifier", + "start": 2278, + "end": 2279, + "loc": { + "start": { + "line": 51, + "column": 12 + }, + "end": { + "line": 51, + "column": 13 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "CallExpression", + "start": 2282, + "end": 2285, + "loc": { + "start": { + "line": 51, + "column": 16 + }, + "end": { + "line": 51, + "column": 19 + } + }, + "callee": { + "type": "Identifier", + "start": 2282, + "end": 2283, + "loc": { + "start": { + "line": 51, + "column": 16 + }, + "end": { + "line": 51, + "column": 17 + } + }, + "name": "f" + }, + "arguments": [], + "optional": false + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 2288, + "end": 2289, + "loc": { + "start": { + "line": 51, + "column": 22 + }, + "end": { + "line": 51, + "column": 23 + } + }, + "name": "c" + } + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A call, and a function or class expression, are no types either.", + "start": 2198, + "end": 2265 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 2292, + "end": 2326, + "loc": { + "start": { + "line": 52, + "column": 1 + }, + "end": { + "line": 52, + "column": 35 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2298, + "end": 2325, + "loc": { + "start": { + "line": 52, + "column": 7 + }, + "end": { + "line": 52, + "column": 34 + } + }, + "id": { + "type": "Identifier", + "start": 2298, + "end": 2300, + "loc": { + "start": { + "line": 52, + "column": 7 + }, + "end": { + "line": 52, + "column": 9 + } + }, + "name": "b5" + }, + "init": { + "type": "BinaryExpression", + "start": 2303, + "end": 2325, + "loc": { + "start": { + "line": 52, + "column": 12 + }, + "end": { + "line": 52, + "column": 34 + } + }, + "left": { + "type": "BinaryExpression", + "start": 2303, + "end": 2321, + "loc": { + "start": { + "line": 52, + "column": 12 + }, + "end": { + "line": 52, + "column": 30 + } + }, + "left": { + "type": "Identifier", + "start": 2303, + "end": 2304, + "loc": { + "start": { + "line": 52, + "column": 12 + }, + "end": { + "line": 52, + "column": 13 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "FunctionExpression", + "start": 2307, + "end": 2321, + "loc": { + "start": { + "line": 52, + "column": 16 + }, + "end": { + "line": 52, + "column": 30 + } + }, + "id": null, + "expression": false, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 2319, + "end": 2321, + "loc": { + "start": { + "line": 52, + "column": 28 + }, + "end": { + "line": 52, + "column": 30 + } + }, + "body": [] + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 2324, + "end": 2325, + "loc": { + "start": { + "line": 52, + "column": 33 + }, + "end": { + "line": 52, + "column": 34 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 2328, + "end": 2356, + "loc": { + "start": { + "line": 53, + "column": 1 + }, + "end": { + "line": 53, + "column": 29 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 2334, + "end": 2355, + "loc": { + "start": { + "line": 53, + "column": 7 + }, + "end": { + "line": 53, + "column": 28 + } + }, + "id": { + "type": "Identifier", + "start": 2334, + "end": 2336, + "loc": { + "start": { + "line": 53, + "column": 7 + }, + "end": { + "line": 53, + "column": 9 + } + }, + "name": "b6" + }, + "init": { + "type": "BinaryExpression", + "start": 2339, + "end": 2355, + "loc": { + "start": { + "line": 53, + "column": 12 + }, + "end": { + "line": 53, + "column": 28 + } + }, + "left": { + "type": "BinaryExpression", + "start": 2339, + "end": 2351, + "loc": { + "start": { + "line": 53, + "column": 12 + }, + "end": { + "line": 53, + "column": 24 + } + }, + "left": { + "type": "Identifier", + "start": 2339, + "end": 2340, + "loc": { + "start": { + "line": 53, + "column": 12 + }, + "end": { + "line": 53, + "column": 13 + } + }, + "name": "x" + }, + "operator": "<", + "right": { + "type": "ClassExpression", + "start": 2343, + "end": 2351, + "loc": { + "start": { + "line": 53, + "column": 16 + }, + "end": { + "line": 53, + "column": 24 + } + }, + "id": null, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 2349, + "end": 2351, + "loc": { + "start": { + "line": 53, + "column": 22 + }, + "end": { + "line": 53, + "column": 24 + } + }, + "body": [] + } + } + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 2354, + "end": 2355, + "loc": { + "start": { + "line": 53, + "column": 27 + }, + "end": { + "line": 53, + "column": 28 + } + }, + "name": "c" + } + } + } + ], + "kind": "const" + } + ], + "sourceType": "module" + }, + "attributes": [ + { + "type": "Attribute", + "start": 8, + "end": 17, + "name": "lang", + "name_loc": { + "start": { + "line": 1, + "column": 8, + "character": 8 + }, + "end": { + "line": 1, + "column": 12, + "character": 12 + } + }, + "value": [ + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "ts", + "data": "ts" + } + ] + } + ] + } +} diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/input.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/input.svelte new file mode 100644 index 000000000..e2cae4b1e --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/input.svelte @@ -0,0 +1,54 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/output_prettier.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/output_prettier.svelte new file mode 100644 index 000000000..7560c654b --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/output_prettier.svelte @@ -0,0 +1,54 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_operand_shell.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_operand_shell.svelte new file mode 100644 index 000000000..d14b5dca2 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_operand_shell.svelte @@ -0,0 +1,54 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_region_break.svelte b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_region_break.svelte new file mode 100644 index 000000000..0731f32f4 --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_chain_type_arg_parens_prettier_divergence/unformatted_ours_region_break.svelte @@ -0,0 +1,60 @@ + diff --git a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/expected.json b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/expected.json index c60899088..c6abd08b9 100644 --- a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/expected.json +++ b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/expected.json @@ -2,7 +2,7 @@ "css": null, "js": [], "start": 0, - "end": 4514, + "end": 3945, "type": "Root", "fragment": { "type": "Fragment", @@ -28,9 +28,9 @@ }, { "type": "Line", - "value": " a closing `>` followed by an identifier is a chained comparison, not type args;", + "value": " a second `<` after the operand opens no nested list — nothing closes one, so the", "start": 256, - "end": 338, + "end": 339, "loc": { "start": { "line": 11, @@ -38,15 +38,15 @@ }, "end": { "line": 11, - "column": 83 + "column": 84 } } }, { "type": "Line", - "value": " this holds across string, numeric, and bare-identifier operands", - "start": 340, - "end": 406, + "value": " line is a chained comparison", + "start": 341, + "end": 372, "loc": { "start": { "line": 12, @@ -54,22 +54,22 @@ }, "end": { "line": 12, - "column": 67 + "column": 32 } } }, { "type": "Line", "value": " a parenthesized ternary operand is a comparison, not a `(b?: T) => ...` function type", - "start": 505, - "end": 593, + "start": 399, + "end": 487, "loc": { "start": { - "line": 18, + "line": 15, "column": 1 }, "end": { - "line": 18, + "line": 15, "column": 89 } } @@ -77,79 +77,31 @@ { "type": "Line", "value": " a `>` inside an array literal belongs to the array, not the relational chain", - "start": 626, - "end": 705, + "start": 520, + "end": 599, "loc": { "start": { - "line": 21, + "line": 18, "column": 1 }, "end": { - "line": 21, + "line": 18, "column": 80 } } }, - { - "type": "Line", - "value": " any expression-starting token after the closing `>` makes it a comparison", - "start": 734, - "end": 810, - "loc": { - "start": { - "line": 24, - "column": 1 - }, - "end": { - "line": 24, - "column": 77 - } - } - }, - { - "type": "Line", - "value": " chain too — literal, unary, array, and object operands behave like the", - "start": 812, - "end": 885, - "loc": { - "start": { - "line": 25, - "column": 1 - }, - "end": { - "line": 25, - "column": 74 - } - } - }, - { - "type": "Line", - "value": " identifier and typeof operands", - "start": 887, - "end": 920, - "loc": { - "start": { - "line": 26, - "column": 1 - }, - "end": { - "line": 26, - "column": 34 - } - } - }, { "type": "Line", "value": " an indexed member access after `<` is a comparison operand, not an indexed access", - "start": 1161, - "end": 1245, + "start": 628, + "end": 712, "loc": { "start": { - "line": 37, + "line": 21, "column": 1 }, "end": { - "line": 37, + "line": 21, "column": 85 } } @@ -157,15 +109,15 @@ { "type": "Line", "value": " type; the `,` that follows it belongs to the enclosing argument, element, or", - "start": 1247, - "end": 1326, + "start": 714, + "end": 793, "loc": { "start": { - "line": 38, + "line": 22, "column": 1 }, "end": { - "line": 38, + "line": 22, "column": 80 } } @@ -173,15 +125,15 @@ { "type": "Line", "value": " property list, whatever the index is", - "start": 1328, - "end": 1367, + "start": 795, + "end": 834, "loc": { "start": { - "line": 39, + "line": 23, "column": 1 }, "end": { - "line": 39, + "line": 23, "column": 40 } } @@ -189,15 +141,15 @@ { "type": "Line", "value": " richer index contents are comparison operands too when no `>` closes the list", - "start": 1576, - "end": 1656, + "start": 1043, + "end": 1123, "loc": { "start": { - "line": 49, + "line": 33, "column": 1 }, "end": { - "line": 49, + "line": 33, "column": 81 } } @@ -205,15 +157,15 @@ { "type": "Line", "value": " arithmetic inside the index is not a type, so the list stays a comparison even", - "start": 1826, - "end": 1907, + "start": 1293, + "end": 1374, "loc": { "start": { - "line": 59, + "line": 43, "column": 1 }, "end": { - "line": 59, + "line": 43, "column": 82 } } @@ -221,15 +173,15 @@ { "type": "Line", "value": " when a `>` closes it; a negated operand and the logical and relational operators", - "start": 1909, - "end": 1992, + "start": 1376, + "end": 1459, "loc": { "start": { - "line": 60, + "line": 44, "column": 1 }, "end": { - "line": 60, + "line": 44, "column": 84 } } @@ -237,63 +189,63 @@ { "type": "Line", "value": " are expressions too, never types", - "start": 1994, - "end": 2029, + "start": 1461, + "end": 1496, "loc": { "start": { - "line": 61, + "line": 45, "column": 1 }, "end": { - "line": 61, + "line": 45, "column": 36 } } }, { "type": "Line", - "value": " a `>` or a shift operator after the indexed operand continues the comparison", - "start": 2159, - "end": 2238, + "value": " a shift operator after the indexed operand continues the comparison chain — the", + "start": 1626, + "end": 1708, "loc": { "start": { - "line": 67, + "line": 51, "column": 1 }, "end": { - "line": 67, - "column": 80 + "line": 51, + "column": 83 } } }, { "type": "Line", - "value": " chain — the `>` run belongs to the operator, not to a type-argument close", - "start": 2240, - "end": 2316, + "value": " `>` run belongs to the operator, not to a type-argument close", + "start": 1710, + "end": 1774, "loc": { "start": { - "line": 68, + "line": 52, "column": 1 }, "end": { - "line": 68, - "column": 77 + "line": 52, + "column": 65 } } }, { "type": "Line", "value": " an identifier that merely starts with `extends` is a fresh statement on the next", - "start": 2403, - "end": 2486, + "start": 1834, + "end": 1917, "loc": { "start": { - "line": 73, + "line": 56, "column": 1 }, "end": { - "line": 73, + "line": 56, "column": 84 } } @@ -301,15 +253,15 @@ { "type": "Line", "value": " line (ASI), not a type constraint", - "start": 2488, - "end": 2524, + "start": 1919, + "end": 1955, "loc": { "start": { - "line": 74, + "line": 57, "column": 1 }, "end": { - "line": 74, + "line": 57, "column": 37 } } @@ -317,15 +269,15 @@ { "type": "Line", "value": " genuine instantiation with a literal/keyword/object/tuple/numeric type arg, or a", - "start": 2562, - "end": 2645, + "start": 1993, + "end": 2076, "loc": { "start": { - "line": 78, + "line": 61, "column": 1 }, "end": { - "line": 78, + "line": 61, "column": 84 } } @@ -333,15 +285,15 @@ { "type": "Line", "value": " function type with an optional param, still parses as type arguments", - "start": 2647, - "end": 2718, + "start": 2078, + "end": 2149, "loc": { "start": { - "line": 79, + "line": 62, "column": 1 }, "end": { - "line": 79, + "line": 62, "column": 72 } } @@ -349,15 +301,15 @@ { "type": "Line", "value": " a generic nested inside a tuple or object-type arg still parses as type arguments", - "start": 2906, - "end": 2990, + "start": 2337, + "end": 2421, "loc": { "start": { - "line": 88, + "line": 71, "column": 1 }, "end": { - "line": 88, + "line": 71, "column": 85 } } @@ -365,15 +317,15 @@ { "type": "Line", "value": " a template literal after the closing `>` is a tagged template on the", - "start": 3198, - "end": 3269, + "start": 2629, + "end": 2700, "loc": { "start": { - "line": 97, + "line": 80, "column": 1 }, "end": { - "line": 97, + "line": 80, "column": 72 } } @@ -381,15 +333,15 @@ { "type": "Line", "value": " instantiation, not a comparison", - "start": 3271, - "end": 3305, + "start": 2702, + "end": 2736, "loc": { "start": { - "line": 98, + "line": 81, "column": 1 }, "end": { - "line": 98, + "line": 81, "column": 35 } } @@ -397,15 +349,15 @@ { "type": "Line", "value": " an indexed access, array, or conditional type argument still parses as type", - "start": 3331, - "end": 3409, + "start": 2762, + "end": 2840, "loc": { "start": { - "line": 101, + "line": 84, "column": 1 }, "end": { - "line": 101, + "line": 84, "column": 79 } } @@ -413,15 +365,15 @@ { "type": "Line", "value": " arguments — the closing `>` is followed by a call", - "start": 3411, - "end": 3463, + "start": 2842, + "end": 2894, "loc": { "start": { - "line": 102, + "line": 85, "column": 1 }, "end": { - "line": 102, + "line": 85, "column": 53 } } @@ -429,15 +381,15 @@ { "type": "Line", "value": " every index content that is itself a valid type — union, intersection, nested", - "start": 3676, - "end": 3756, + "start": 3107, + "end": 3187, "loc": { "start": { - "line": 111, + "line": 94, "column": 1 }, "end": { - "line": 111, + "line": 94, "column": 81 } } @@ -445,15 +397,15 @@ { "type": "Line", "value": " index, numeric literal, and conditional — makes the list type arguments", - "start": 3758, - "end": 3832, + "start": 3189, + "end": 3263, "loc": { "start": { - "line": 112, + "line": 95, "column": 1 }, "end": { - "line": 112, + "line": 95, "column": 75 } } @@ -461,15 +413,15 @@ { "type": "Line", "value": " a numeric literal index continues into a type exactly as a reference index does —", - "start": 4100, - "end": 4184, + "start": 3531, + "end": 3615, "loc": { "start": { - "line": 123, + "line": 106, "column": 1 }, "end": { - "line": 123, + "line": 106, "column": 85 } } @@ -477,15 +429,15 @@ { "type": "Line", "value": " union, intersection, and conditional forms are type arguments whichever operand", - "start": 4186, - "end": 4268, + "start": 3617, + "end": 3699, "loc": { "start": { - "line": 124, + "line": 107, "column": 1 }, "end": { - "line": 124, + "line": 107, "column": 83 } } @@ -493,15 +445,15 @@ { "type": "Line", "value": " kind opens them, and an exponent's own sign belongs to the literal", - "start": 4270, - "end": 4339, + "start": 3701, + "end": 3770, "loc": { "start": { - "line": 125, + "line": 108, "column": 1 }, "end": { - "line": 125, + "line": 108, "column": 70 } } @@ -510,19 +462,19 @@ "instance": { "type": "Script", "start": 0, - "end": 4513, + "end": 3944, "context": "default", "content": { "type": "Program", "start": 18, - "end": 4504, + "end": 3935, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 131, + "line": 114, "column": 9 } }, @@ -1378,8 +1330,8 @@ }, { "type": "VariableDeclaration", - "start": 408, - "end": 431, + "start": 374, + "end": 396, "loc": { "start": { "line": 13, @@ -1387,14 +1339,14 @@ }, "end": { "line": 13, - "column": 24 + "column": 23 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 414, - "end": 430, + "start": 380, + "end": 395, "loc": { "start": { "line": 13, @@ -1402,13 +1354,13 @@ }, "end": { "line": 13, - "column": 23 + "column": 22 } }, "id": { "type": "Identifier", - "start": 414, - "end": 416, + "start": 380, + "end": 383, "loc": { "start": { "line": 13, @@ -1416,87 +1368,86 @@ }, "end": { "line": 13, - "column": 9 + "column": 10 } }, - "name": "a8" + "name": "a11" }, "init": { "type": "BinaryExpression", - "start": 419, - "end": 430, + "start": 386, + "end": 395, "loc": { "start": { "line": 13, - "column": 12 + "column": 13 }, "end": { "line": 13, - "column": 23 + "column": 22 } }, "left": { "type": "BinaryExpression", - "start": 419, - "end": 426, + "start": 386, + "end": 391, "loc": { "start": { "line": 13, - "column": 12 + "column": 13 }, "end": { "line": 13, - "column": 19 + "column": 18 } }, "left": { "type": "Identifier", - "start": 419, - "end": 420, + "start": 386, + "end": 387, "loc": { "start": { "line": 13, - "column": 12 + "column": 13 }, "end": { "line": 13, - "column": 13 + "column": 14 } }, - "name": "x" + "name": "a" }, "operator": "<", "right": { - "type": "Literal", - "start": 423, - "end": 426, + "type": "Identifier", + "start": 390, + "end": 391, "loc": { "start": { "line": 13, - "column": 16 + "column": 17 }, "end": { "line": 13, - "column": 19 + "column": 18 } }, - "value": "b", - "raw": "'b'" + "name": "b" } }, - "operator": ">", + "operator": "<", "right": { "type": "Identifier", - "start": 429, - "end": 430, + "start": 394, + "end": 395, "loc": { "start": { "line": 13, - "column": 22 + "column": 21 }, "end": { "line": 13, - "column": 23 + "column": 22 } }, "name": "c" @@ -1508,2092 +1459,363 @@ "leadingComments": [ { "type": "Line", - "value": " a closing `>` followed by an identifier is a chained comparison, not type args;", + "value": " a second `<` after the operand opens no nested list — nothing closes one, so the", "start": 256, - "end": 338 + "end": 339 }, { "type": "Line", - "value": " this holds across string, numeric, and bare-identifier operands", - "start": 340, - "end": 406 + "value": " line is a chained comparison", + "start": 341, + "end": 372 } ] }, { "type": "VariableDeclaration", - "start": 433, - "end": 454, + "start": 489, + "end": 517, "loc": { "start": { - "line": 14, + "line": 16, "column": 1 }, "end": { - "line": 14, - "column": 22 + "line": 16, + "column": 29 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 439, - "end": 453, + "start": 495, + "end": 516, "loc": { "start": { - "line": 14, + "line": 16, "column": 7 }, "end": { - "line": 14, - "column": 21 + "line": 16, + "column": 28 } }, "id": { "type": "Identifier", - "start": 439, - "end": 441, + "start": 495, + "end": 498, "loc": { "start": { - "line": 14, + "line": 16, "column": 7 }, "end": { - "line": 14, - "column": 9 + "line": 16, + "column": 10 } }, - "name": "a9" + "name": "a12" }, "init": { "type": "BinaryExpression", - "start": 444, - "end": 453, + "start": 501, + "end": 516, "loc": { "start": { - "line": 14, - "column": 12 + "line": 16, + "column": 13 }, "end": { - "line": 14, - "column": 21 + "line": 16, + "column": 28 } }, "left": { - "type": "BinaryExpression", - "start": 444, - "end": 449, + "type": "Identifier", + "start": 501, + "end": 502, "loc": { "start": { - "line": 14, - "column": 12 + "line": 16, + "column": 13 }, "end": { - "line": 14, - "column": 17 + "line": 16, + "column": 14 } }, - "left": { + "name": "x" + }, + "operator": "<", + "right": { + "type": "ConditionalExpression", + "start": 506, + "end": 515, + "loc": { + "start": { + "line": 16, + "column": 18 + }, + "end": { + "line": 16, + "column": 27 + } + }, + "test": { "type": "Identifier", - "start": 444, - "end": 445, + "start": 506, + "end": 507, "loc": { "start": { - "line": 14, - "column": 12 + "line": 16, + "column": 18 }, "end": { - "line": 14, - "column": 13 + "line": 16, + "column": 19 } }, - "name": "x" + "name": "b" }, - "operator": "<", - "right": { - "type": "Literal", - "start": 448, - "end": 449, + "consequent": { + "type": "Identifier", + "start": 510, + "end": 511, "loc": { "start": { - "line": 14, - "column": 16 + "line": 16, + "column": 22 }, "end": { - "line": 14, - "column": 17 + "line": 16, + "column": 23 } }, - "value": 1, - "raw": "1" - } - }, - "operator": ">", - "right": { - "type": "Identifier", - "start": 452, - "end": 453, - "loc": { - "start": { - "line": 14, - "column": 20 - }, - "end": { - "line": 14, - "column": 21 - } + "name": "c" }, - "name": "c" + "alternate": { + "type": "Identifier", + "start": 514, + "end": 515, + "loc": { + "start": { + "line": 16, + "column": 26 + }, + "end": { + "line": 16, + "column": 27 + } + }, + "name": "d" + } } } } ], - "kind": "const" + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " a parenthesized ternary operand is a comparison, not a `(b?: T) => ...` function type", + "start": 399, + "end": 487 + } + ] }, { "type": "VariableDeclaration", - "start": 456, - "end": 478, + "start": 601, + "end": 625, "loc": { "start": { - "line": 15, + "line": 19, "column": 1 }, "end": { - "line": 15, - "column": 23 + "line": 19, + "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 462, - "end": 477, + "start": 607, + "end": 624, "loc": { "start": { - "line": 15, + "line": 19, "column": 7 }, "end": { - "line": 15, - "column": 22 + "line": 19, + "column": 24 } }, "id": { "type": "Identifier", - "start": 462, - "end": 465, + "start": 607, + "end": 610, "loc": { "start": { - "line": 15, + "line": 19, "column": 7 }, "end": { - "line": 15, + "line": 19, "column": 10 } }, - "name": "a10" + "name": "a13" }, "init": { "type": "BinaryExpression", - "start": 468, - "end": 477, + "start": 613, + "end": 624, "loc": { "start": { - "line": 15, + "line": 19, "column": 13 }, "end": { - "line": 15, - "column": 22 + "line": 19, + "column": 24 } }, "left": { - "type": "BinaryExpression", - "start": 468, - "end": 473, + "type": "Identifier", + "start": 613, + "end": 614, "loc": { "start": { - "line": 15, + "line": 19, "column": 13 }, "end": { - "line": 15, - "column": 18 + "line": 19, + "column": 14 } }, - "left": { - "type": "Identifier", - "start": 468, - "end": 469, - "loc": { - "start": { - "line": 15, - "column": 13 - }, - "end": { - "line": 15, - "column": 14 - } - }, - "name": "a" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 472, - "end": 473, - "loc": { - "start": { - "line": 15, - "column": 17 - }, - "end": { - "line": 15, - "column": 18 - } - }, - "name": "b" - } + "name": "x" }, - "operator": ">", + "operator": "<", "right": { - "type": "Identifier", - "start": 476, - "end": 477, + "type": "ArrayExpression", + "start": 617, + "end": 624, "loc": { "start": { - "line": 15, - "column": 21 + "line": 19, + "column": 17 }, "end": { - "line": 15, - "column": 22 + "line": 19, + "column": 24 } }, - "name": "c" - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 480, - "end": 502, - "loc": { - "start": { - "line": 16, - "column": 1 - }, - "end": { - "line": 16, - "column": 23 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 486, - "end": 501, - "loc": { - "start": { - "line": 16, - "column": 7 - }, - "end": { - "line": 16, - "column": 22 - } - }, - "id": { - "type": "Identifier", - "start": 486, - "end": 489, - "loc": { - "start": { - "line": 16, - "column": 7 - }, - "end": { - "line": 16, - "column": 10 - } - }, - "name": "a11" - }, - "init": { - "type": "BinaryExpression", - "start": 492, - "end": 501, - "loc": { - "start": { - "line": 16, - "column": 13 - }, - "end": { - "line": 16, - "column": 22 - } - }, - "left": { - "type": "BinaryExpression", - "start": 492, - "end": 497, - "loc": { - "start": { - "line": 16, - "column": 13 - }, - "end": { - "line": 16, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 492, - "end": 493, - "loc": { - "start": { - "line": 16, - "column": 13 - }, - "end": { - "line": 16, - "column": 14 - } - }, - "name": "a" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 496, - "end": 497, - "loc": { - "start": { - "line": 16, - "column": 17 - }, - "end": { - "line": 16, - "column": 18 - } - }, - "name": "b" - } - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 500, - "end": 501, - "loc": { - "start": { - "line": 16, - "column": 21 - }, - "end": { - "line": 16, - "column": 22 - } - }, - "name": "c" - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 595, - "end": 623, - "loc": { - "start": { - "line": 19, - "column": 1 - }, - "end": { - "line": 19, - "column": 29 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 601, - "end": 622, - "loc": { - "start": { - "line": 19, - "column": 7 - }, - "end": { - "line": 19, - "column": 28 - } - }, - "id": { - "type": "Identifier", - "start": 601, - "end": 604, - "loc": { - "start": { - "line": 19, - "column": 7 - }, - "end": { - "line": 19, - "column": 10 - } - }, - "name": "a12" - }, - "init": { - "type": "BinaryExpression", - "start": 607, - "end": 622, - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 28 - } - }, - "left": { - "type": "Identifier", - "start": 607, - "end": 608, - "loc": { - "start": { - "line": 19, - "column": 13 - }, - "end": { - "line": 19, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "ConditionalExpression", - "start": 612, - "end": 621, - "loc": { - "start": { - "line": 19, - "column": 18 - }, - "end": { - "line": 19, - "column": 27 - } - }, - "test": { - "type": "Identifier", - "start": 612, - "end": 613, - "loc": { - "start": { - "line": 19, - "column": 18 - }, - "end": { - "line": 19, - "column": 19 - } - }, - "name": "b" - }, - "consequent": { - "type": "Identifier", - "start": 616, - "end": 617, - "loc": { - "start": { - "line": 19, - "column": 22 - }, - "end": { - "line": 19, - "column": 23 - } - }, - "name": "c" - }, - "alternate": { - "type": "Identifier", - "start": 620, - "end": 621, - "loc": { - "start": { - "line": 19, - "column": 26 - }, - "end": { - "line": 19, - "column": 27 - } - }, - "name": "d" - } - } - } - } - ], - "kind": "const", - "leadingComments": [ - { - "type": "Line", - "value": " a parenthesized ternary operand is a comparison, not a `(b?: T) => ...` function type", - "start": 505, - "end": 593 - } - ] - }, - { - "type": "VariableDeclaration", - "start": 707, - "end": 731, - "loc": { - "start": { - "line": 22, - "column": 1 - }, - "end": { - "line": 22, - "column": 25 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 713, - "end": 730, - "loc": { - "start": { - "line": 22, - "column": 7 - }, - "end": { - "line": 22, - "column": 24 - } - }, - "id": { - "type": "Identifier", - "start": 713, - "end": 716, - "loc": { - "start": { - "line": 22, - "column": 7 - }, - "end": { - "line": 22, - "column": 10 - } - }, - "name": "a13" - }, - "init": { - "type": "BinaryExpression", - "start": 719, - "end": 730, - "loc": { - "start": { - "line": 22, - "column": 13 - }, - "end": { - "line": 22, - "column": 24 - } - }, - "left": { - "type": "Identifier", - "start": 719, - "end": 720, - "loc": { - "start": { - "line": 22, - "column": 13 - }, - "end": { - "line": 22, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "ArrayExpression", - "start": 723, - "end": 730, - "loc": { - "start": { - "line": 22, - "column": 17 - }, - "end": { - "line": 22, - "column": 24 - } - }, - "elements": [ - { - "type": "BinaryExpression", - "start": 724, - "end": 729, - "loc": { - "start": { - "line": 22, - "column": 18 - }, - "end": { - "line": 22, - "column": 23 - } - }, - "left": { - "type": "Identifier", - "start": 724, - "end": 725, - "loc": { - "start": { - "line": 22, - "column": 18 - }, - "end": { - "line": 22, - "column": 19 - } - }, - "name": "a" - }, - "operator": ">", - "right": { - "type": "Identifier", - "start": 728, - "end": 729, - "loc": { - "start": { - "line": 22, - "column": 22 - }, - "end": { - "line": 22, - "column": 23 - } - }, - "name": "b" - } - } - ] - } - } - } - ], - "kind": "const", - "leadingComments": [ - { - "type": "Line", - "value": " a `>` inside an array literal belongs to the array, not the relational chain", - "start": 626, - "end": 705 - } - ] - }, - { - "type": "VariableDeclaration", - "start": 922, - "end": 944, - "loc": { - "start": { - "line": 27, - "column": 1 - }, - "end": { - "line": 27, - "column": 23 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 928, - "end": 943, - "loc": { - "start": { - "line": 27, - "column": 7 - }, - "end": { - "line": 27, - "column": 22 - } - }, - "id": { - "type": "Identifier", - "start": 928, - "end": 931, - "loc": { - "start": { - "line": 27, - "column": 7 - }, - "end": { - "line": 27, - "column": 10 - } - }, - "name": "a14" - }, - "init": { - "type": "BinaryExpression", - "start": 934, - "end": 943, - "loc": { - "start": { - "line": 27, - "column": 13 - }, - "end": { - "line": 27, - "column": 22 - } - }, - "left": { - "type": "BinaryExpression", - "start": 934, - "end": 939, - "loc": { - "start": { - "line": 27, - "column": 13 - }, - "end": { - "line": 27, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 934, - "end": 935, - "loc": { - "start": { - "line": 27, - "column": 13 - }, - "end": { - "line": 27, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 938, - "end": 939, - "loc": { - "start": { - "line": 27, - "column": 17 - }, - "end": { - "line": 27, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "Literal", - "start": 942, - "end": 943, - "loc": { - "start": { - "line": 27, - "column": 21 - }, - "end": { - "line": 27, - "column": 22 - } - }, - "value": 1, - "raw": "1" - } - } - } - ], - "kind": "const", - "leadingComments": [ - { - "type": "Line", - "value": " any expression-starting token after the closing `>` makes it a comparison", - "start": 734, - "end": 810 - }, - { - "type": "Line", - "value": " chain too — literal, unary, array, and object operands behave like the", - "start": 812, - "end": 885 - }, - { - "type": "Line", - "value": " identifier and typeof operands", - "start": 887, - "end": 920 - } - ] - }, - { - "type": "VariableDeclaration", - "start": 946, - "end": 970, - "loc": { - "start": { - "line": 28, - "column": 1 - }, - "end": { - "line": 28, - "column": 25 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 952, - "end": 969, - "loc": { - "start": { - "line": 28, - "column": 7 - }, - "end": { - "line": 28, - "column": 24 - } - }, - "id": { - "type": "Identifier", - "start": 952, - "end": 955, - "loc": { - "start": { - "line": 28, - "column": 7 - }, - "end": { - "line": 28, - "column": 10 - } - }, - "name": "a15" - }, - "init": { - "type": "BinaryExpression", - "start": 958, - "end": 969, - "loc": { - "start": { - "line": 28, - "column": 13 - }, - "end": { - "line": 28, - "column": 24 - } - }, - "left": { - "type": "BinaryExpression", - "start": 958, - "end": 963, - "loc": { - "start": { - "line": 28, - "column": 13 - }, - "end": { - "line": 28, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 958, - "end": 959, - "loc": { - "start": { - "line": 28, - "column": 13 - }, - "end": { - "line": 28, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 962, - "end": 963, - "loc": { - "start": { - "line": 28, - "column": 17 - }, - "end": { - "line": 28, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "Literal", - "start": 966, - "end": 969, - "loc": { - "start": { - "line": 28, - "column": 21 - }, - "end": { - "line": 28, - "column": 24 - } - }, - "value": "b", - "raw": "'b'" - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 972, - "end": 995, - "loc": { - "start": { - "line": 29, - "column": 1 - }, - "end": { - "line": 29, - "column": 24 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 978, - "end": 994, - "loc": { - "start": { - "line": 29, - "column": 7 - }, - "end": { - "line": 29, - "column": 23 - } - }, - "id": { - "type": "Identifier", - "start": 978, - "end": 981, - "loc": { - "start": { - "line": 29, - "column": 7 - }, - "end": { - "line": 29, - "column": 10 - } - }, - "name": "a16" - }, - "init": { - "type": "BinaryExpression", - "start": 984, - "end": 994, - "loc": { - "start": { - "line": 29, - "column": 13 - }, - "end": { - "line": 29, - "column": 23 - } - }, - "left": { - "type": "BinaryExpression", - "start": 984, - "end": 989, - "loc": { - "start": { - "line": 29, - "column": 13 - }, - "end": { - "line": 29, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 984, - "end": 985, - "loc": { - "start": { - "line": 29, - "column": 13 - }, - "end": { - "line": 29, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 988, - "end": 989, - "loc": { - "start": { - "line": 29, - "column": 17 - }, - "end": { - "line": 29, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "UnaryExpression", - "start": 992, - "end": 994, - "loc": { - "start": { - "line": 29, - "column": 21 - }, - "end": { - "line": 29, - "column": 23 - } - }, - "operator": "!", - "prefix": true, - "argument": { - "type": "Identifier", - "start": 993, - "end": 994, - "loc": { - "start": { - "line": 29, - "column": 22 - }, - "end": { - "line": 29, - "column": 23 - } - }, - "name": "c" - } - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 997, - "end": 1020, - "loc": { - "start": { - "line": 30, - "column": 1 - }, - "end": { - "line": 30, - "column": 24 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1003, - "end": 1019, - "loc": { - "start": { - "line": 30, - "column": 7 - }, - "end": { - "line": 30, - "column": 23 - } - }, - "id": { - "type": "Identifier", - "start": 1003, - "end": 1006, - "loc": { - "start": { - "line": 30, - "column": 7 - }, - "end": { - "line": 30, - "column": 10 - } - }, - "name": "a17" - }, - "init": { - "type": "BinaryExpression", - "start": 1009, - "end": 1019, - "loc": { - "start": { - "line": 30, - "column": 13 - }, - "end": { - "line": 30, - "column": 23 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1009, - "end": 1014, - "loc": { - "start": { - "line": 30, - "column": 13 - }, - "end": { - "line": 30, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1009, - "end": 1010, - "loc": { - "start": { - "line": 30, - "column": 13 - }, - "end": { - "line": 30, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1013, - "end": 1014, - "loc": { - "start": { - "line": 30, - "column": 17 - }, - "end": { - "line": 30, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "UnaryExpression", - "start": 1017, - "end": 1019, - "loc": { - "start": { - "line": 30, - "column": 21 - }, - "end": { - "line": 30, - "column": 23 - } - }, - "operator": "~", - "prefix": true, - "argument": { - "type": "Identifier", - "start": 1018, - "end": 1019, - "loc": { - "start": { - "line": 30, - "column": 22 - }, - "end": { - "line": 30, - "column": 23 - } - }, - "name": "c" - } - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 1022, - "end": 1045, - "loc": { - "start": { - "line": 31, - "column": 1 - }, - "end": { - "line": 31, - "column": 24 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1028, - "end": 1044, - "loc": { - "start": { - "line": 31, - "column": 7 - }, - "end": { - "line": 31, - "column": 23 - } - }, - "id": { - "type": "Identifier", - "start": 1028, - "end": 1031, - "loc": { - "start": { - "line": 31, - "column": 7 - }, - "end": { - "line": 31, - "column": 10 - } - }, - "name": "a18" - }, - "init": { - "type": "BinaryExpression", - "start": 1034, - "end": 1044, - "loc": { - "start": { - "line": 31, - "column": 13 - }, - "end": { - "line": 31, - "column": 23 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1034, - "end": 1039, - "loc": { - "start": { - "line": 31, - "column": 13 - }, - "end": { - "line": 31, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1034, - "end": 1035, - "loc": { - "start": { - "line": 31, - "column": 13 - }, - "end": { - "line": 31, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1038, - "end": 1039, - "loc": { - "start": { - "line": 31, - "column": 17 - }, - "end": { - "line": 31, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "UnaryExpression", - "start": 1042, - "end": 1044, - "loc": { - "start": { - "line": 31, - "column": 21 - }, - "end": { - "line": 31, - "column": 23 - } - }, - "operator": "-", - "prefix": true, - "argument": { - "type": "Literal", - "start": 1043, - "end": 1044, - "loc": { - "start": { - "line": 31, - "column": 22 - }, - "end": { - "line": 31, - "column": 23 - } - }, - "value": 1, - "raw": "1" - } - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 1047, - "end": 1070, - "loc": { - "start": { - "line": 32, - "column": 1 - }, - "end": { - "line": 32, - "column": 24 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1053, - "end": 1069, - "loc": { - "start": { - "line": 32, - "column": 7 - }, - "end": { - "line": 32, - "column": 23 - } - }, - "id": { - "type": "Identifier", - "start": 1053, - "end": 1056, - "loc": { - "start": { - "line": 32, - "column": 7 - }, - "end": { - "line": 32, - "column": 10 - } - }, - "name": "a19" - }, - "init": { - "type": "BinaryExpression", - "start": 1059, - "end": 1069, - "loc": { - "start": { - "line": 32, - "column": 13 - }, - "end": { - "line": 32, - "column": 23 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1059, - "end": 1064, - "loc": { - "start": { - "line": 32, - "column": 13 - }, - "end": { - "line": 32, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1059, - "end": 1060, - "loc": { - "start": { - "line": 32, - "column": 13 - }, - "end": { - "line": 32, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1063, - "end": 1064, - "loc": { - "start": { - "line": 32, - "column": 17 - }, - "end": { - "line": 32, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "UnaryExpression", - "start": 1067, - "end": 1069, - "loc": { - "start": { - "line": 32, - "column": 21 - }, - "end": { - "line": 32, - "column": 23 - } - }, - "operator": "+", - "prefix": true, - "argument": { - "type": "Literal", - "start": 1068, - "end": 1069, - "loc": { - "start": { - "line": 32, - "column": 22 - }, - "end": { - "line": 32, - "column": 23 - } - }, - "value": 1, - "raw": "1" - } - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 1072, - "end": 1096, - "loc": { - "start": { - "line": 33, - "column": 1 - }, - "end": { - "line": 33, - "column": 25 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1078, - "end": 1095, - "loc": { - "start": { - "line": 33, - "column": 7 - }, - "end": { - "line": 33, - "column": 24 - } - }, - "id": { - "type": "Identifier", - "start": 1078, - "end": 1081, - "loc": { - "start": { - "line": 33, - "column": 7 - }, - "end": { - "line": 33, - "column": 10 - } - }, - "name": "a20" - }, - "init": { - "type": "BinaryExpression", - "start": 1084, - "end": 1095, - "loc": { - "start": { - "line": 33, - "column": 13 - }, - "end": { - "line": 33, - "column": 24 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1084, - "end": 1089, - "loc": { - "start": { - "line": 33, - "column": 13 - }, - "end": { - "line": 33, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1084, - "end": 1085, - "loc": { - "start": { - "line": 33, - "column": 13 - }, - "end": { - "line": 33, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1088, - "end": 1089, - "loc": { - "start": { - "line": 33, - "column": 17 - }, - "end": { - "line": 33, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "ArrayExpression", - "start": 1092, - "end": 1095, - "loc": { - "start": { - "line": 33, - "column": 21 - }, - "end": { - "line": 33, - "column": 24 - } - }, - "elements": [ - { - "type": "Literal", - "start": 1093, - "end": 1094, - "loc": { - "start": { - "line": 33, - "column": 22 - }, - "end": { - "line": 33, - "column": 23 - } - }, - "value": 0, - "raw": "0" - } - ] - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 1098, - "end": 1127, - "loc": { - "start": { - "line": 34, - "column": 1 - }, - "end": { - "line": 34, - "column": 30 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1104, - "end": 1126, - "loc": { - "start": { - "line": 34, - "column": 7 - }, - "end": { - "line": 34, - "column": 29 - } - }, - "id": { - "type": "Identifier", - "start": 1104, - "end": 1107, - "loc": { - "start": { - "line": 34, - "column": 7 - }, - "end": { - "line": 34, - "column": 10 - } - }, - "name": "a21" - }, - "init": { - "type": "BinaryExpression", - "start": 1110, - "end": 1126, - "loc": { - "start": { - "line": 34, - "column": 13 - }, - "end": { - "line": 34, - "column": 29 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1110, - "end": 1115, - "loc": { - "start": { - "line": 34, - "column": 13 - }, - "end": { - "line": 34, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1110, - "end": 1111, - "loc": { - "start": { - "line": 34, - "column": 13 - }, - "end": { - "line": 34, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1114, - "end": 1115, - "loc": { - "start": { - "line": 34, - "column": 17 - }, - "end": { - "line": 34, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "ObjectExpression", - "start": 1118, - "end": 1126, - "loc": { - "start": { - "line": 34, - "column": 21 - }, - "end": { - "line": 34, - "column": 29 - } - }, - "properties": [ - { - "type": "Property", - "start": 1120, - "end": 1124, - "loc": { - "start": { - "line": 34, - "column": 23 - }, - "end": { - "line": 34, - "column": 27 - } - }, - "method": false, - "shorthand": false, - "computed": false, - "key": { - "type": "Identifier", - "start": 1120, - "end": 1121, - "loc": { - "start": { - "line": 34, - "column": 23 - }, - "end": { - "line": 34, - "column": 24 - } - }, - "name": "a" - }, - "value": { - "type": "Literal", - "start": 1123, - "end": 1124, - "loc": { - "start": { - "line": 34, - "column": 26 - }, - "end": { - "line": 34, - "column": 27 - } - }, - "value": 1, - "raw": "1" - }, - "kind": "init" - } - ] - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 1129, - "end": 1158, - "loc": { - "start": { - "line": 35, - "column": 1 - }, - "end": { - "line": 35, - "column": 30 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 1135, - "end": 1157, - "loc": { - "start": { - "line": 35, - "column": 7 - }, - "end": { - "line": 35, - "column": 29 - } - }, - "id": { - "type": "Identifier", - "start": 1135, - "end": 1138, - "loc": { - "start": { - "line": 35, - "column": 7 - }, - "end": { - "line": 35, - "column": 10 - } - }, - "name": "a22" - }, - "init": { - "type": "BinaryExpression", - "start": 1141, - "end": 1157, - "loc": { - "start": { - "line": 35, - "column": 13 - }, - "end": { - "line": 35, - "column": 29 - } - }, - "left": { - "type": "BinaryExpression", - "start": 1141, - "end": 1146, - "loc": { - "start": { - "line": 35, - "column": 13 - }, - "end": { - "line": 35, - "column": 18 - } - }, - "left": { - "type": "Identifier", - "start": 1141, - "end": 1142, - "loc": { - "start": { - "line": 35, - "column": 13 - }, - "end": { - "line": 35, - "column": 14 - } - }, - "name": "x" - }, - "operator": "<", - "right": { - "type": "Identifier", - "start": 1145, - "end": 1146, - "loc": { - "start": { - "line": 35, - "column": 17 - }, - "end": { - "line": 35, - "column": 18 - } - }, - "name": "y" - } - }, - "operator": ">", - "right": { - "type": "UnaryExpression", - "start": 1149, - "end": 1157, - "loc": { - "start": { - "line": 35, - "column": 21 - }, - "end": { - "line": 35, - "column": 29 - } - }, - "operator": "typeof", - "prefix": true, - "argument": { - "type": "Identifier", - "start": 1156, - "end": 1157, - "loc": { - "start": { - "line": 35, - "column": 28 + "elements": [ + { + "type": "BinaryExpression", + "start": 618, + "end": 623, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 23 + } }, - "end": { - "line": 35, - "column": 29 + "left": { + "type": "Identifier", + "start": 618, + "end": 619, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 19 + } + }, + "name": "a" + }, + "operator": ">", + "right": { + "type": "Identifier", + "start": 622, + "end": 623, + "loc": { + "start": { + "line": 19, + "column": 22 + }, + "end": { + "line": 19, + "column": 23 + } + }, + "name": "b" } - }, - "name": "c" - } + } + ] } } } ], - "kind": "const" + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " a `>` inside an array literal belongs to the array, not the relational chain", + "start": 520, + "end": 599 + } + ] }, { "type": "ExpressionStatement", - "start": 1369, - "end": 1385, + "start": 836, + "end": 852, "loc": { "start": { - "line": 40, + "line": 24, "column": 1 }, "end": { - "line": 40, + "line": 24, "column": 17 } }, "expression": { "type": "CallExpression", - "start": 1369, - "end": 1384, + "start": 836, + "end": 851, "loc": { "start": { - "line": 40, + "line": 24, "column": 1 }, "end": { - "line": 40, + "line": 24, "column": 16 } }, "callee": { "type": "Identifier", - "start": 1369, - "end": 1371, + "start": 836, + "end": 838, "loc": { "start": { - "line": 40, + "line": 24, "column": 1 }, "end": { - "line": 40, + "line": 24, "column": 3 } }, @@ -3602,29 +1824,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1372, - "end": 1380, + "start": 839, + "end": 847, "loc": { "start": { - "line": 40, + "line": 24, "column": 4 }, "end": { - "line": 40, + "line": 24, "column": 12 } }, "left": { "type": "Identifier", - "start": 1372, - "end": 1373, + "start": 839, + "end": 840, "loc": { "start": { - "line": 40, + "line": 24, "column": 4 }, "end": { - "line": 40, + "line": 24, "column": 5 } }, @@ -3633,29 +1855,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1376, - "end": 1380, + "start": 843, + "end": 847, "loc": { "start": { - "line": 40, + "line": 24, "column": 8 }, "end": { - "line": 40, + "line": 24, "column": 12 } }, "object": { "type": "Identifier", - "start": 1376, - "end": 1377, + "start": 843, + "end": 844, "loc": { "start": { - "line": 40, + "line": 24, "column": 8 }, "end": { - "line": 40, + "line": 24, "column": 9 } }, @@ -3663,15 +1885,15 @@ }, "property": { "type": "Identifier", - "start": 1378, - "end": 1379, + "start": 845, + "end": 846, "loc": { "start": { - "line": 40, + "line": 24, "column": 10 }, "end": { - "line": 40, + "line": 24, "column": 11 } }, @@ -3683,15 +1905,15 @@ }, { "type": "Identifier", - "start": 1382, - "end": 1383, + "start": 849, + "end": 850, "loc": { "start": { - "line": 40, + "line": 24, "column": 14 }, "end": { - "line": 40, + "line": 24, "column": 15 } }, @@ -3704,62 +1926,62 @@ { "type": "Line", "value": " an indexed member access after `<` is a comparison operand, not an indexed access", - "start": 1161, - "end": 1245 + "start": 628, + "end": 712 }, { "type": "Line", "value": " type; the `,` that follows it belongs to the enclosing argument, element, or", - "start": 1247, - "end": 1326 + "start": 714, + "end": 793 }, { "type": "Line", "value": " property list, whatever the index is", - "start": 1328, - "end": 1367 + "start": 795, + "end": 834 } ] }, { "type": "ExpressionStatement", - "start": 1387, - "end": 1405, + "start": 854, + "end": 872, "loc": { "start": { - "line": 41, + "line": 25, "column": 1 }, "end": { - "line": 41, + "line": 25, "column": 19 } }, "expression": { "type": "CallExpression", - "start": 1387, - "end": 1404, + "start": 854, + "end": 871, "loc": { "start": { - "line": 41, + "line": 25, "column": 1 }, "end": { - "line": 41, + "line": 25, "column": 18 } }, "callee": { "type": "Identifier", - "start": 1387, - "end": 1389, + "start": 854, + "end": 856, "loc": { "start": { - "line": 41, + "line": 25, "column": 1 }, "end": { - "line": 41, + "line": 25, "column": 3 } }, @@ -3768,29 +1990,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1390, - "end": 1400, + "start": 857, + "end": 867, "loc": { "start": { - "line": 41, + "line": 25, "column": 4 }, "end": { - "line": 41, + "line": 25, "column": 14 } }, "left": { "type": "Identifier", - "start": 1390, - "end": 1391, + "start": 857, + "end": 858, "loc": { "start": { - "line": 41, + "line": 25, "column": 4 }, "end": { - "line": 41, + "line": 25, "column": 5 } }, @@ -3799,29 +2021,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1394, - "end": 1400, + "start": 861, + "end": 867, "loc": { "start": { - "line": 41, + "line": 25, "column": 8 }, "end": { - "line": 41, + "line": 25, "column": 14 } }, "object": { "type": "Identifier", - "start": 1394, - "end": 1395, + "start": 861, + "end": 862, "loc": { "start": { - "line": 41, + "line": 25, "column": 8 }, "end": { - "line": 41, + "line": 25, "column": 9 } }, @@ -3829,15 +2051,15 @@ }, "property": { "type": "Literal", - "start": 1396, - "end": 1399, + "start": 863, + "end": 866, "loc": { "start": { - "line": 41, + "line": 25, "column": 10 }, "end": { - "line": 41, + "line": 25, "column": 13 } }, @@ -3850,15 +2072,15 @@ }, { "type": "Identifier", - "start": 1402, - "end": 1403, + "start": 869, + "end": 870, "loc": { "start": { - "line": 41, + "line": 25, "column": 16 }, "end": { - "line": 41, + "line": 25, "column": 17 } }, @@ -3870,43 +2092,43 @@ }, { "type": "ExpressionStatement", - "start": 1407, - "end": 1430, + "start": 874, + "end": 897, "loc": { "start": { - "line": 42, + "line": 26, "column": 1 }, "end": { - "line": 42, + "line": 26, "column": 24 } }, "expression": { "type": "CallExpression", - "start": 1407, - "end": 1429, + "start": 874, + "end": 896, "loc": { "start": { - "line": 42, + "line": 26, "column": 1 }, "end": { - "line": 42, + "line": 26, "column": 23 } }, "callee": { "type": "Identifier", - "start": 1407, - "end": 1409, + "start": 874, + "end": 876, "loc": { "start": { - "line": 42, + "line": 26, "column": 1 }, "end": { - "line": 42, + "line": 26, "column": 3 } }, @@ -3915,29 +2137,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1410, - "end": 1425, + "start": 877, + "end": 892, "loc": { "start": { - "line": 42, + "line": 26, "column": 4 }, "end": { - "line": 42, + "line": 26, "column": 19 } }, "left": { "type": "Identifier", - "start": 1410, - "end": 1411, + "start": 877, + "end": 878, "loc": { "start": { - "line": 42, + "line": 26, "column": 4 }, "end": { - "line": 42, + "line": 26, "column": 5 } }, @@ -3946,29 +2168,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1414, - "end": 1425, + "start": 881, + "end": 892, "loc": { "start": { - "line": 42, + "line": 26, "column": 8 }, "end": { - "line": 42, + "line": 26, "column": 19 } }, "object": { "type": "Identifier", - "start": 1414, - "end": 1415, + "start": 881, + "end": 882, "loc": { "start": { - "line": 42, + "line": 26, "column": 8 }, "end": { - "line": 42, + "line": 26, "column": 9 } }, @@ -3976,15 +2198,15 @@ }, "property": { "type": "UnaryExpression", - "start": 1416, - "end": 1424, + "start": 883, + "end": 891, "loc": { "start": { - "line": 42, + "line": 26, "column": 10 }, "end": { - "line": 42, + "line": 26, "column": 18 } }, @@ -3992,15 +2214,15 @@ "prefix": true, "argument": { "type": "Identifier", - "start": 1423, - "end": 1424, + "start": 890, + "end": 891, "loc": { "start": { - "line": 42, + "line": 26, "column": 17 }, "end": { - "line": 42, + "line": 26, "column": 18 } }, @@ -4013,15 +2235,15 @@ }, { "type": "Identifier", - "start": 1427, - "end": 1428, + "start": 894, + "end": 895, "loc": { "start": { - "line": 42, + "line": 26, "column": 21 }, "end": { - "line": 42, + "line": 26, "column": 22 } }, @@ -4033,44 +2255,44 @@ }, { "type": "VariableDeclaration", - "start": 1432, - "end": 1458, + "start": 899, + "end": 925, "loc": { "start": { - "line": 43, + "line": 27, "column": 1 }, "end": { - "line": 43, + "line": 27, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 1438, - "end": 1457, + "start": 905, + "end": 924, "loc": { "start": { - "line": 43, + "line": 27, "column": 7 }, "end": { - "line": 43, + "line": 27, "column": 26 } }, "id": { "type": "Identifier", - "start": 1438, - "end": 1441, + "start": 905, + "end": 908, "loc": { "start": { - "line": 43, + "line": 27, "column": 7 }, "end": { - "line": 43, + "line": 27, "column": 10 } }, @@ -4078,44 +2300,44 @@ }, "init": { "type": "ArrayExpression", - "start": 1444, - "end": 1457, + "start": 911, + "end": 924, "loc": { "start": { - "line": 43, + "line": 27, "column": 13 }, "end": { - "line": 43, + "line": 27, "column": 26 } }, "elements": [ { "type": "BinaryExpression", - "start": 1445, - "end": 1453, + "start": 912, + "end": 920, "loc": { "start": { - "line": 43, + "line": 27, "column": 14 }, "end": { - "line": 43, + "line": 27, "column": 22 } }, "left": { "type": "Identifier", - "start": 1445, - "end": 1446, + "start": 912, + "end": 913, "loc": { "start": { - "line": 43, + "line": 27, "column": 14 }, "end": { - "line": 43, + "line": 27, "column": 15 } }, @@ -4124,29 +2346,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1449, - "end": 1453, + "start": 916, + "end": 920, "loc": { "start": { - "line": 43, + "line": 27, "column": 18 }, "end": { - "line": 43, + "line": 27, "column": 22 } }, "object": { "type": "Identifier", - "start": 1449, - "end": 1450, + "start": 916, + "end": 917, "loc": { "start": { - "line": 43, + "line": 27, "column": 18 }, "end": { - "line": 43, + "line": 27, "column": 19 } }, @@ -4154,15 +2376,15 @@ }, "property": { "type": "Identifier", - "start": 1451, - "end": 1452, + "start": 918, + "end": 919, "loc": { "start": { - "line": 43, + "line": 27, "column": 20 }, "end": { - "line": 43, + "line": 27, "column": 21 } }, @@ -4174,15 +2396,15 @@ }, { "type": "Identifier", - "start": 1455, - "end": 1456, + "start": 922, + "end": 923, "loc": { "start": { - "line": 43, + "line": 27, "column": 24 }, "end": { - "line": 43, + "line": 27, "column": 25 } }, @@ -4196,44 +2418,44 @@ }, { "type": "VariableDeclaration", - "start": 1460, - "end": 1494, + "start": 927, + "end": 961, "loc": { "start": { - "line": 44, + "line": 28, "column": 1 }, "end": { - "line": 44, + "line": 28, "column": 35 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 1466, - "end": 1493, + "start": 933, + "end": 960, "loc": { "start": { - "line": 44, + "line": 28, "column": 7 }, "end": { - "line": 44, + "line": 28, "column": 34 } }, "id": { "type": "Identifier", - "start": 1466, - "end": 1469, + "start": 933, + "end": 936, "loc": { "start": { - "line": 44, + "line": 28, "column": 7 }, "end": { - "line": 44, + "line": 28, "column": 10 } }, @@ -4241,30 +2463,30 @@ }, "init": { "type": "ObjectExpression", - "start": 1472, - "end": 1493, + "start": 939, + "end": 960, "loc": { "start": { - "line": 44, + "line": 28, "column": 13 }, "end": { - "line": 44, + "line": 28, "column": 34 } }, "properties": [ { "type": "Property", - "start": 1474, - "end": 1485, + "start": 941, + "end": 952, "loc": { "start": { - "line": 44, + "line": 28, "column": 15 }, "end": { - "line": 44, + "line": 28, "column": 26 } }, @@ -4273,15 +2495,15 @@ "computed": false, "key": { "type": "Identifier", - "start": 1474, - "end": 1475, + "start": 941, + "end": 942, "loc": { "start": { - "line": 44, + "line": 28, "column": 15 }, "end": { - "line": 44, + "line": 28, "column": 16 } }, @@ -4289,29 +2511,29 @@ }, "value": { "type": "BinaryExpression", - "start": 1477, - "end": 1485, + "start": 944, + "end": 952, "loc": { "start": { - "line": 44, + "line": 28, "column": 18 }, "end": { - "line": 44, + "line": 28, "column": 26 } }, "left": { "type": "Identifier", - "start": 1477, - "end": 1478, + "start": 944, + "end": 945, "loc": { "start": { - "line": 44, + "line": 28, "column": 18 }, "end": { - "line": 44, + "line": 28, "column": 19 } }, @@ -4320,29 +2542,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1481, - "end": 1485, + "start": 948, + "end": 952, "loc": { "start": { - "line": 44, + "line": 28, "column": 22 }, "end": { - "line": 44, + "line": 28, "column": 26 } }, "object": { "type": "Identifier", - "start": 1481, - "end": 1482, + "start": 948, + "end": 949, "loc": { "start": { - "line": 44, + "line": 28, "column": 22 }, "end": { - "line": 44, + "line": 28, "column": 23 } }, @@ -4350,15 +2572,15 @@ }, "property": { "type": "Identifier", - "start": 1483, - "end": 1484, + "start": 950, + "end": 951, "loc": { "start": { - "line": 44, + "line": 28, "column": 24 }, "end": { - "line": 44, + "line": 28, "column": 25 } }, @@ -4372,15 +2594,15 @@ }, { "type": "Property", - "start": 1487, - "end": 1491, + "start": 954, + "end": 958, "loc": { "start": { - "line": 44, + "line": 28, "column": 28 }, "end": { - "line": 44, + "line": 28, "column": 32 } }, @@ -4389,15 +2611,15 @@ "computed": false, "key": { "type": "Identifier", - "start": 1487, - "end": 1488, + "start": 954, + "end": 955, "loc": { "start": { - "line": 44, + "line": 28, "column": 28 }, "end": { - "line": 44, + "line": 28, "column": 29 } }, @@ -4405,15 +2627,15 @@ }, "value": { "type": "Identifier", - "start": 1490, - "end": 1491, + "start": 957, + "end": 958, "loc": { "start": { - "line": 44, + "line": 28, "column": 31 }, "end": { - "line": 44, + "line": 28, "column": 32 } }, @@ -4429,44 +2651,44 @@ }, { "type": "VariableDeclaration", - "start": 1496, - "end": 1522, + "start": 963, + "end": 989, "loc": { "start": { - "line": 45, + "line": 29, "column": 1 }, "end": { - "line": 45, + "line": 29, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 1502, - "end": 1521, + "start": 969, + "end": 988, "loc": { "start": { - "line": 45, + "line": 29, "column": 7 }, "end": { - "line": 45, + "line": 29, "column": 26 } }, "id": { "type": "Identifier", - "start": 1502, - "end": 1505, + "start": 969, + "end": 972, "loc": { "start": { - "line": 45, + "line": 29, "column": 7 }, "end": { - "line": 45, + "line": 29, "column": 10 } }, @@ -4474,44 +2696,44 @@ }, "init": { "type": "SequenceExpression", - "start": 1509, - "end": 1520, + "start": 976, + "end": 987, "loc": { "start": { - "line": 45, + "line": 29, "column": 14 }, "end": { - "line": 45, + "line": 29, "column": 25 } }, "expressions": [ { "type": "BinaryExpression", - "start": 1509, - "end": 1517, + "start": 976, + "end": 984, "loc": { "start": { - "line": 45, + "line": 29, "column": 14 }, "end": { - "line": 45, + "line": 29, "column": 22 } }, "left": { "type": "Identifier", - "start": 1509, - "end": 1510, + "start": 976, + "end": 977, "loc": { "start": { - "line": 45, + "line": 29, "column": 14 }, "end": { - "line": 45, + "line": 29, "column": 15 } }, @@ -4520,29 +2742,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1513, - "end": 1517, + "start": 980, + "end": 984, "loc": { "start": { - "line": 45, + "line": 29, "column": 18 }, "end": { - "line": 45, + "line": 29, "column": 22 } }, "object": { "type": "Identifier", - "start": 1513, - "end": 1514, + "start": 980, + "end": 981, "loc": { "start": { - "line": 45, + "line": 29, "column": 18 }, "end": { - "line": 45, + "line": 29, "column": 19 } }, @@ -4550,15 +2772,15 @@ }, "property": { "type": "Identifier", - "start": 1515, - "end": 1516, + "start": 982, + "end": 983, "loc": { "start": { - "line": 45, + "line": 29, "column": 20 }, "end": { - "line": 45, + "line": 29, "column": 21 } }, @@ -4570,15 +2792,15 @@ }, { "type": "Identifier", - "start": 1519, - "end": 1520, + "start": 986, + "end": 987, "loc": { "start": { - "line": 45, + "line": 29, "column": 24 }, "end": { - "line": 45, + "line": 29, "column": 25 } }, @@ -4592,44 +2814,44 @@ }, { "type": "VariableDeclaration", - "start": 1524, - "end": 1547, + "start": 991, + "end": 1014, "loc": { "start": { - "line": 46, + "line": 30, "column": 1 }, "end": { - "line": 46, + "line": 30, "column": 24 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 1530, - "end": 1546, + "start": 997, + "end": 1013, "loc": { "start": { - "line": 46, + "line": 30, "column": 7 }, "end": { - "line": 46, + "line": 30, "column": 23 } }, "id": { "type": "Identifier", - "start": 1530, - "end": 1533, + "start": 997, + "end": 1000, "loc": { "start": { - "line": 46, + "line": 30, "column": 7 }, "end": { - "line": 46, + "line": 30, "column": 10 } }, @@ -4637,29 +2859,29 @@ }, "init": { "type": "BinaryExpression", - "start": 1536, - "end": 1546, + "start": 1003, + "end": 1013, "loc": { "start": { - "line": 46, + "line": 30, "column": 13 }, "end": { - "line": 46, + "line": 30, "column": 23 } }, "left": { "type": "Identifier", - "start": 1536, - "end": 1537, + "start": 1003, + "end": 1004, "loc": { "start": { - "line": 46, + "line": 30, "column": 13 }, "end": { - "line": 46, + "line": 30, "column": 14 } }, @@ -4668,43 +2890,43 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1540, - "end": 1546, + "start": 1007, + "end": 1013, "loc": { "start": { - "line": 46, + "line": 30, "column": 17 }, "end": { - "line": 46, + "line": 30, "column": 23 } }, "object": { "type": "MemberExpression", - "start": 1540, - "end": 1543, + "start": 1007, + "end": 1010, "loc": { "start": { - "line": 46, + "line": 30, "column": 17 }, "end": { - "line": 46, + "line": 30, "column": 20 } }, "object": { "type": "Identifier", - "start": 1540, - "end": 1541, + "start": 1007, + "end": 1008, "loc": { "start": { - "line": 46, + "line": 30, "column": 17 }, "end": { - "line": 46, + "line": 30, "column": 18 } }, @@ -4712,15 +2934,15 @@ }, "property": { "type": "Identifier", - "start": 1542, - "end": 1543, + "start": 1009, + "end": 1010, "loc": { "start": { - "line": 46, + "line": 30, "column": 19 }, "end": { - "line": 46, + "line": 30, "column": 20 } }, @@ -4731,15 +2953,15 @@ }, "property": { "type": "Identifier", - "start": 1544, - "end": 1545, + "start": 1011, + "end": 1012, "loc": { "start": { - "line": 46, + "line": 30, "column": 21 }, "end": { - "line": 46, + "line": 30, "column": 22 } }, @@ -4755,44 +2977,44 @@ }, { "type": "VariableDeclaration", - "start": 1549, - "end": 1573, + "start": 1016, + "end": 1040, "loc": { "start": { - "line": 47, + "line": 31, "column": 1 }, "end": { - "line": 47, + "line": 31, "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 1555, - "end": 1572, + "start": 1022, + "end": 1039, "loc": { "start": { - "line": 47, + "line": 31, "column": 7 }, "end": { - "line": 47, + "line": 31, "column": 24 } }, "id": { "type": "Identifier", - "start": 1555, - "end": 1558, + "start": 1022, + "end": 1025, "loc": { "start": { - "line": 47, + "line": 31, "column": 7 }, "end": { - "line": 47, + "line": 31, "column": 10 } }, @@ -4800,29 +3022,29 @@ }, "init": { "type": "BinaryExpression", - "start": 1561, - "end": 1572, + "start": 1028, + "end": 1039, "loc": { "start": { - "line": 47, + "line": 31, "column": 13 }, "end": { - "line": 47, + "line": 31, "column": 24 } }, "left": { "type": "Identifier", - "start": 1561, - "end": 1562, + "start": 1028, + "end": 1029, "loc": { "start": { - "line": 47, + "line": 31, "column": 13 }, "end": { - "line": 47, + "line": 31, "column": 14 } }, @@ -4831,43 +3053,43 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1565, - "end": 1572, + "start": 1032, + "end": 1039, "loc": { "start": { - "line": 47, + "line": 31, "column": 17 }, "end": { - "line": 47, + "line": 31, "column": 24 } }, "object": { "type": "MemberExpression", - "start": 1565, - "end": 1569, + "start": 1032, + "end": 1036, "loc": { "start": { - "line": 47, + "line": 31, "column": 17 }, "end": { - "line": 47, + "line": 31, "column": 21 } }, "object": { "type": "Identifier", - "start": 1565, - "end": 1566, + "start": 1032, + "end": 1033, "loc": { "start": { - "line": 47, + "line": 31, "column": 17 }, "end": { - "line": 47, + "line": 31, "column": 18 } }, @@ -4875,15 +3097,15 @@ }, "property": { "type": "Identifier", - "start": 1567, - "end": 1568, + "start": 1034, + "end": 1035, "loc": { "start": { - "line": 47, + "line": 31, "column": 19 }, "end": { - "line": 47, + "line": 31, "column": 20 } }, @@ -4894,15 +3116,15 @@ }, "property": { "type": "Identifier", - "start": 1570, - "end": 1571, + "start": 1037, + "end": 1038, "loc": { "start": { - "line": 47, + "line": 31, "column": 22 }, "end": { - "line": 47, + "line": 31, "column": 23 } }, @@ -4918,43 +3140,43 @@ }, { "type": "ExpressionStatement", - "start": 1658, - "end": 1678, + "start": 1125, + "end": 1145, "loc": { "start": { - "line": 50, + "line": 34, "column": 1 }, "end": { - "line": 50, + "line": 34, "column": 21 } }, "expression": { "type": "CallExpression", - "start": 1658, - "end": 1677, + "start": 1125, + "end": 1144, "loc": { "start": { - "line": 50, + "line": 34, "column": 1 }, "end": { - "line": 50, + "line": 34, "column": 20 } }, "callee": { "type": "Identifier", - "start": 1658, - "end": 1660, + "start": 1125, + "end": 1127, "loc": { "start": { - "line": 50, + "line": 34, "column": 1 }, "end": { - "line": 50, + "line": 34, "column": 3 } }, @@ -4963,29 +3185,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1661, - "end": 1673, + "start": 1128, + "end": 1140, "loc": { "start": { - "line": 50, + "line": 34, "column": 4 }, "end": { - "line": 50, + "line": 34, "column": 16 } }, "left": { "type": "Identifier", - "start": 1661, - "end": 1662, + "start": 1128, + "end": 1129, "loc": { "start": { - "line": 50, + "line": 34, "column": 4 }, "end": { - "line": 50, + "line": 34, "column": 5 } }, @@ -4994,29 +3216,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1665, - "end": 1673, + "start": 1132, + "end": 1140, "loc": { "start": { - "line": 50, + "line": 34, "column": 8 }, "end": { - "line": 50, + "line": 34, "column": 16 } }, "object": { "type": "Identifier", - "start": 1665, - "end": 1666, + "start": 1132, + "end": 1133, "loc": { "start": { - "line": 50, + "line": 34, "column": 8 }, "end": { - "line": 50, + "line": 34, "column": 9 } }, @@ -5024,29 +3246,29 @@ }, "property": { "type": "BinaryExpression", - "start": 1667, - "end": 1672, + "start": 1134, + "end": 1139, "loc": { "start": { - "line": 50, + "line": 34, "column": 10 }, "end": { - "line": 50, + "line": 34, "column": 15 } }, "left": { "type": "Identifier", - "start": 1667, - "end": 1668, + "start": 1134, + "end": 1135, "loc": { "start": { - "line": 50, + "line": 34, "column": 10 }, "end": { - "line": 50, + "line": 34, "column": 11 } }, @@ -5055,15 +3277,15 @@ "operator": "|", "right": { "type": "Identifier", - "start": 1671, - "end": 1672, + "start": 1138, + "end": 1139, "loc": { "start": { - "line": 50, + "line": 34, "column": 14 }, "end": { - "line": 50, + "line": 34, "column": 15 } }, @@ -5076,15 +3298,15 @@ }, { "type": "Identifier", - "start": 1675, - "end": 1676, + "start": 1142, + "end": 1143, "loc": { "start": { - "line": 50, + "line": 34, "column": 18 }, "end": { - "line": 50, + "line": 34, "column": 19 } }, @@ -5097,50 +3319,50 @@ { "type": "Line", "value": " richer index contents are comparison operands too when no `>` closes the list", - "start": 1576, - "end": 1656 + "start": 1043, + "end": 1123 } ] }, { "type": "ExpressionStatement", - "start": 1680, - "end": 1700, + "start": 1147, + "end": 1167, "loc": { "start": { - "line": 51, + "line": 35, "column": 1 }, "end": { - "line": 51, + "line": 35, "column": 21 } }, "expression": { "type": "CallExpression", - "start": 1680, - "end": 1699, + "start": 1147, + "end": 1166, "loc": { "start": { - "line": 51, + "line": 35, "column": 1 }, "end": { - "line": 51, + "line": 35, "column": 20 } }, "callee": { "type": "Identifier", - "start": 1680, - "end": 1682, + "start": 1147, + "end": 1149, "loc": { "start": { - "line": 51, + "line": 35, "column": 1 }, "end": { - "line": 51, + "line": 35, "column": 3 } }, @@ -5149,29 +3371,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1683, - "end": 1695, + "start": 1150, + "end": 1162, "loc": { "start": { - "line": 51, + "line": 35, "column": 4 }, "end": { - "line": 51, + "line": 35, "column": 16 } }, "left": { "type": "Identifier", - "start": 1683, - "end": 1684, + "start": 1150, + "end": 1151, "loc": { "start": { - "line": 51, + "line": 35, "column": 4 }, "end": { - "line": 51, + "line": 35, "column": 5 } }, @@ -5180,29 +3402,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1687, - "end": 1695, + "start": 1154, + "end": 1162, "loc": { "start": { - "line": 51, + "line": 35, "column": 8 }, "end": { - "line": 51, + "line": 35, "column": 16 } }, "object": { "type": "Identifier", - "start": 1687, - "end": 1688, + "start": 1154, + "end": 1155, "loc": { "start": { - "line": 51, + "line": 35, "column": 8 }, "end": { - "line": 51, + "line": 35, "column": 9 } }, @@ -5210,29 +3432,29 @@ }, "property": { "type": "BinaryExpression", - "start": 1689, - "end": 1694, + "start": 1156, + "end": 1161, "loc": { "start": { - "line": 51, + "line": 35, "column": 10 }, "end": { - "line": 51, + "line": 35, "column": 15 } }, "left": { "type": "Identifier", - "start": 1689, - "end": 1690, + "start": 1156, + "end": 1157, "loc": { "start": { - "line": 51, + "line": 35, "column": 10 }, "end": { - "line": 51, + "line": 35, "column": 11 } }, @@ -5241,15 +3463,15 @@ "operator": "&", "right": { "type": "Identifier", - "start": 1693, - "end": 1694, + "start": 1160, + "end": 1161, "loc": { "start": { - "line": 51, + "line": 35, "column": 14 }, "end": { - "line": 51, + "line": 35, "column": 15 } }, @@ -5262,15 +3484,15 @@ }, { "type": "Identifier", - "start": 1697, - "end": 1698, + "start": 1164, + "end": 1165, "loc": { "start": { - "line": 51, + "line": 35, "column": 18 }, "end": { - "line": 51, + "line": 35, "column": 19 } }, @@ -5282,43 +3504,43 @@ }, { "type": "ExpressionStatement", - "start": 1702, - "end": 1721, + "start": 1169, + "end": 1188, "loc": { "start": { - "line": 52, + "line": 36, "column": 1 }, "end": { - "line": 52, + "line": 36, "column": 20 } }, "expression": { "type": "CallExpression", - "start": 1702, - "end": 1720, + "start": 1169, + "end": 1187, "loc": { "start": { - "line": 52, + "line": 36, "column": 1 }, "end": { - "line": 52, + "line": 36, "column": 19 } }, "callee": { "type": "Identifier", - "start": 1702, - "end": 1704, + "start": 1169, + "end": 1171, "loc": { "start": { - "line": 52, + "line": 36, "column": 1 }, "end": { - "line": 52, + "line": 36, "column": 3 } }, @@ -5327,29 +3549,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1705, - "end": 1716, + "start": 1172, + "end": 1183, "loc": { "start": { - "line": 52, + "line": 36, "column": 4 }, "end": { - "line": 52, + "line": 36, "column": 15 } }, "left": { "type": "Identifier", - "start": 1705, - "end": 1706, + "start": 1172, + "end": 1173, "loc": { "start": { - "line": 52, + "line": 36, "column": 4 }, "end": { - "line": 52, + "line": 36, "column": 5 } }, @@ -5358,29 +3580,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1709, - "end": 1716, + "start": 1176, + "end": 1183, "loc": { "start": { - "line": 52, + "line": 36, "column": 8 }, "end": { - "line": 52, + "line": 36, "column": 15 } }, "object": { "type": "Identifier", - "start": 1709, - "end": 1710, + "start": 1176, + "end": 1177, "loc": { "start": { - "line": 52, + "line": 36, "column": 8 }, "end": { - "line": 52, + "line": 36, "column": 9 } }, @@ -5388,29 +3610,29 @@ }, "property": { "type": "MemberExpression", - "start": 1711, - "end": 1715, + "start": 1178, + "end": 1182, "loc": { "start": { - "line": 52, + "line": 36, "column": 10 }, "end": { - "line": 52, + "line": 36, "column": 14 } }, "object": { "type": "Identifier", - "start": 1711, - "end": 1712, + "start": 1178, + "end": 1179, "loc": { "start": { - "line": 52, + "line": 36, "column": 10 }, "end": { - "line": 52, + "line": 36, "column": 11 } }, @@ -5418,15 +3640,15 @@ }, "property": { "type": "Identifier", - "start": 1713, - "end": 1714, + "start": 1180, + "end": 1181, "loc": { "start": { - "line": 52, + "line": 36, "column": 12 }, "end": { - "line": 52, + "line": 36, "column": 13 } }, @@ -5441,15 +3663,15 @@ }, { "type": "Identifier", - "start": 1718, - "end": 1719, + "start": 1185, + "end": 1186, "loc": { "start": { - "line": 52, + "line": 36, "column": 17 }, "end": { - "line": 52, + "line": 36, "column": 18 } }, @@ -5461,43 +3683,43 @@ }, { "type": "ExpressionStatement", - "start": 1723, - "end": 1739, + "start": 1190, + "end": 1206, "loc": { "start": { - "line": 53, + "line": 37, "column": 1 }, "end": { - "line": 53, + "line": 37, "column": 17 } }, "expression": { "type": "CallExpression", - "start": 1723, - "end": 1738, + "start": 1190, + "end": 1205, "loc": { "start": { - "line": 53, + "line": 37, "column": 1 }, "end": { - "line": 53, + "line": 37, "column": 16 } }, "callee": { "type": "Identifier", - "start": 1723, - "end": 1725, + "start": 1190, + "end": 1192, "loc": { "start": { - "line": 53, + "line": 37, "column": 1 }, "end": { - "line": 53, + "line": 37, "column": 3 } }, @@ -5506,29 +3728,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1726, - "end": 1734, + "start": 1193, + "end": 1201, "loc": { "start": { - "line": 53, + "line": 37, "column": 4 }, "end": { - "line": 53, + "line": 37, "column": 12 } }, "left": { "type": "Identifier", - "start": 1726, - "end": 1727, + "start": 1193, + "end": 1194, "loc": { "start": { - "line": 53, + "line": 37, "column": 4 }, "end": { - "line": 53, + "line": 37, "column": 5 } }, @@ -5537,29 +3759,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1730, - "end": 1734, + "start": 1197, + "end": 1201, "loc": { "start": { - "line": 53, + "line": 37, "column": 8 }, "end": { - "line": 53, + "line": 37, "column": 12 } }, "object": { "type": "Identifier", - "start": 1730, - "end": 1731, + "start": 1197, + "end": 1198, "loc": { "start": { - "line": 53, + "line": 37, "column": 8 }, "end": { - "line": 53, + "line": 37, "column": 9 } }, @@ -5567,15 +3789,15 @@ }, "property": { "type": "Literal", - "start": 1732, - "end": 1733, + "start": 1199, + "end": 1200, "loc": { "start": { - "line": 53, + "line": 37, "column": 10 }, "end": { - "line": 53, + "line": 37, "column": 11 } }, @@ -5588,15 +3810,15 @@ }, { "type": "Identifier", - "start": 1736, - "end": 1737, + "start": 1203, + "end": 1204, "loc": { "start": { - "line": 53, + "line": 37, "column": 14 }, "end": { - "line": 53, + "line": 37, "column": 15 } }, @@ -5608,43 +3830,43 @@ }, { "type": "ExpressionStatement", - "start": 1741, - "end": 1758, + "start": 1208, + "end": 1225, "loc": { "start": { - "line": 54, + "line": 38, "column": 1 }, "end": { - "line": 54, + "line": 38, "column": 18 } }, "expression": { "type": "CallExpression", - "start": 1741, - "end": 1757, + "start": 1208, + "end": 1224, "loc": { "start": { - "line": 54, + "line": 38, "column": 1 }, "end": { - "line": 54, + "line": 38, "column": 17 } }, "callee": { "type": "Identifier", - "start": 1741, - "end": 1743, + "start": 1208, + "end": 1210, "loc": { "start": { - "line": 54, + "line": 38, "column": 1 }, "end": { - "line": 54, + "line": 38, "column": 3 } }, @@ -5653,29 +3875,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1744, - "end": 1753, + "start": 1211, + "end": 1220, "loc": { "start": { - "line": 54, + "line": 38, "column": 4 }, "end": { - "line": 54, + "line": 38, "column": 13 } }, "left": { "type": "Identifier", - "start": 1744, - "end": 1745, + "start": 1211, + "end": 1212, "loc": { "start": { - "line": 54, + "line": 38, "column": 4 }, "end": { - "line": 54, + "line": 38, "column": 5 } }, @@ -5684,29 +3906,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1748, - "end": 1753, + "start": 1215, + "end": 1220, "loc": { "start": { - "line": 54, + "line": 38, "column": 8 }, "end": { - "line": 54, + "line": 38, "column": 13 } }, "object": { "type": "Identifier", - "start": 1748, - "end": 1749, + "start": 1215, + "end": 1216, "loc": { "start": { - "line": 54, + "line": 38, "column": 8 }, "end": { - "line": 54, + "line": 38, "column": 9 } }, @@ -5714,15 +3936,15 @@ }, "property": { "type": "UnaryExpression", - "start": 1750, - "end": 1752, + "start": 1217, + "end": 1219, "loc": { "start": { - "line": 54, + "line": 38, "column": 10 }, "end": { - "line": 54, + "line": 38, "column": 12 } }, @@ -5730,15 +3952,15 @@ "prefix": true, "argument": { "type": "Literal", - "start": 1751, - "end": 1752, + "start": 1218, + "end": 1219, "loc": { "start": { - "line": 54, + "line": 38, "column": 11 }, "end": { - "line": 54, + "line": 38, "column": 12 } }, @@ -5752,15 +3974,15 @@ }, { "type": "Identifier", - "start": 1755, - "end": 1756, + "start": 1222, + "end": 1223, "loc": { "start": { - "line": 54, + "line": 38, "column": 15 }, "end": { - "line": 54, + "line": 38, "column": 16 } }, @@ -5772,43 +3994,43 @@ }, { "type": "ExpressionStatement", - "start": 1760, - "end": 1778, + "start": 1227, + "end": 1245, "loc": { "start": { - "line": 55, + "line": 39, "column": 1 }, "end": { - "line": 55, + "line": 39, "column": 19 } }, "expression": { "type": "CallExpression", - "start": 1760, - "end": 1777, + "start": 1227, + "end": 1244, "loc": { "start": { - "line": 55, + "line": 39, "column": 1 }, "end": { - "line": 55, + "line": 39, "column": 18 } }, "callee": { "type": "Identifier", - "start": 1760, - "end": 1762, + "start": 1227, + "end": 1229, "loc": { "start": { - "line": 55, + "line": 39, "column": 1 }, "end": { - "line": 55, + "line": 39, "column": 3 } }, @@ -5817,29 +4039,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1763, - "end": 1773, + "start": 1230, + "end": 1240, "loc": { "start": { - "line": 55, + "line": 39, "column": 4 }, "end": { - "line": 55, + "line": 39, "column": 14 } }, "left": { "type": "Identifier", - "start": 1763, - "end": 1764, + "start": 1230, + "end": 1231, "loc": { "start": { - "line": 55, + "line": 39, "column": 4 }, "end": { - "line": 55, + "line": 39, "column": 5 } }, @@ -5848,29 +4070,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1767, - "end": 1773, + "start": 1234, + "end": 1240, "loc": { "start": { - "line": 55, + "line": 39, "column": 8 }, "end": { - "line": 55, + "line": 39, "column": 14 } }, "object": { "type": "Identifier", - "start": 1767, - "end": 1768, + "start": 1234, + "end": 1235, "loc": { "start": { - "line": 55, + "line": 39, "column": 8 }, "end": { - "line": 55, + "line": 39, "column": 9 } }, @@ -5878,29 +4100,29 @@ }, "property": { "type": "MemberExpression", - "start": 1769, - "end": 1772, + "start": 1236, + "end": 1239, "loc": { "start": { - "line": 55, + "line": 39, "column": 10 }, "end": { - "line": 55, + "line": 39, "column": 13 } }, "object": { "type": "Identifier", - "start": 1769, - "end": 1770, + "start": 1236, + "end": 1237, "loc": { "start": { - "line": 55, + "line": 39, "column": 10 }, "end": { - "line": 55, + "line": 39, "column": 11 } }, @@ -5908,15 +4130,15 @@ }, "property": { "type": "Identifier", - "start": 1771, - "end": 1772, + "start": 1238, + "end": 1239, "loc": { "start": { - "line": 55, + "line": 39, "column": 12 }, "end": { - "line": 55, + "line": 39, "column": 13 } }, @@ -5931,15 +4153,15 @@ }, { "type": "Identifier", - "start": 1775, - "end": 1776, + "start": 1242, + "end": 1243, "loc": { "start": { - "line": 55, + "line": 39, "column": 16 }, "end": { - "line": 55, + "line": 39, "column": 17 } }, @@ -5951,43 +4173,43 @@ }, { "type": "ExpressionStatement", - "start": 1780, - "end": 1801, + "start": 1247, + "end": 1268, "loc": { "start": { - "line": 56, + "line": 40, "column": 1 }, "end": { - "line": 56, + "line": 40, "column": 22 } }, "expression": { "type": "CallExpression", - "start": 1780, - "end": 1800, + "start": 1247, + "end": 1267, "loc": { "start": { - "line": 56, + "line": 40, "column": 1 }, "end": { - "line": 56, + "line": 40, "column": 21 } }, "callee": { "type": "Identifier", - "start": 1780, - "end": 1782, + "start": 1247, + "end": 1249, "loc": { "start": { - "line": 56, + "line": 40, "column": 1 }, "end": { - "line": 56, + "line": 40, "column": 3 } }, @@ -5996,29 +4218,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1783, - "end": 1796, + "start": 1250, + "end": 1263, "loc": { "start": { - "line": 56, + "line": 40, "column": 4 }, "end": { - "line": 56, + "line": 40, "column": 17 } }, "left": { "type": "Identifier", - "start": 1783, - "end": 1784, + "start": 1250, + "end": 1251, "loc": { "start": { - "line": 56, + "line": 40, "column": 4 }, "end": { - "line": 56, + "line": 40, "column": 5 } }, @@ -6027,29 +4249,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1787, - "end": 1796, + "start": 1254, + "end": 1263, "loc": { "start": { - "line": 56, + "line": 40, "column": 8 }, "end": { - "line": 56, + "line": 40, "column": 17 } }, "object": { "type": "Identifier", - "start": 1787, - "end": 1788, + "start": 1254, + "end": 1255, "loc": { "start": { - "line": 56, + "line": 40, "column": 8 }, "end": { - "line": 56, + "line": 40, "column": 9 } }, @@ -6057,29 +4279,29 @@ }, "property": { "type": "MemberExpression", - "start": 1789, - "end": 1795, + "start": 1256, + "end": 1262, "loc": { "start": { - "line": 56, + "line": 40, "column": 10 }, "end": { - "line": 56, + "line": 40, "column": 16 } }, "object": { "type": "Identifier", - "start": 1789, - "end": 1790, + "start": 1256, + "end": 1257, "loc": { "start": { - "line": 56, + "line": 40, "column": 10 }, "end": { - "line": 56, + "line": 40, "column": 11 } }, @@ -6087,15 +4309,15 @@ }, "property": { "type": "Literal", - "start": 1791, - "end": 1794, + "start": 1258, + "end": 1261, "loc": { "start": { - "line": 56, + "line": 40, "column": 12 }, "end": { - "line": 56, + "line": 40, "column": 15 } }, @@ -6111,15 +4333,15 @@ }, { "type": "Identifier", - "start": 1798, - "end": 1799, + "start": 1265, + "end": 1266, "loc": { "start": { - "line": 56, + "line": 40, "column": 19 }, "end": { - "line": 56, + "line": 40, "column": 20 } }, @@ -6131,43 +4353,43 @@ }, { "type": "ExpressionStatement", - "start": 1803, - "end": 1823, + "start": 1270, + "end": 1290, "loc": { "start": { - "line": 57, + "line": 41, "column": 1 }, "end": { - "line": 57, + "line": 41, "column": 21 } }, "expression": { "type": "CallExpression", - "start": 1803, - "end": 1822, + "start": 1270, + "end": 1289, "loc": { "start": { - "line": 57, + "line": 41, "column": 1 }, "end": { - "line": 57, + "line": 41, "column": 20 } }, "callee": { "type": "Identifier", - "start": 1803, - "end": 1805, + "start": 1270, + "end": 1272, "loc": { "start": { - "line": 57, + "line": 41, "column": 1 }, "end": { - "line": 57, + "line": 41, "column": 3 } }, @@ -6176,29 +4398,29 @@ "arguments": [ { "type": "BinaryExpression", - "start": 1806, - "end": 1818, + "start": 1273, + "end": 1285, "loc": { "start": { - "line": 57, + "line": 41, "column": 4 }, "end": { - "line": 57, + "line": 41, "column": 16 } }, "left": { "type": "Identifier", - "start": 1806, - "end": 1807, + "start": 1273, + "end": 1274, "loc": { "start": { - "line": 57, + "line": 41, "column": 4 }, "end": { - "line": 57, + "line": 41, "column": 5 } }, @@ -6207,29 +4429,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 1810, - "end": 1818, + "start": 1277, + "end": 1285, "loc": { "start": { - "line": 57, + "line": 41, "column": 8 }, "end": { - "line": 57, + "line": 41, "column": 16 } }, "object": { "type": "Identifier", - "start": 1810, - "end": 1811, + "start": 1277, + "end": 1278, "loc": { "start": { - "line": 57, + "line": 41, "column": 8 }, "end": { - "line": 57, + "line": 41, "column": 9 } }, @@ -6237,29 +4459,29 @@ }, "property": { "type": "BinaryExpression", - "start": 1812, - "end": 1817, + "start": 1279, + "end": 1284, "loc": { "start": { - "line": 57, + "line": 41, "column": 10 }, "end": { - "line": 57, + "line": 41, "column": 15 } }, "left": { "type": "Identifier", - "start": 1812, - "end": 1813, + "start": 1279, + "end": 1280, "loc": { "start": { - "line": 57, + "line": 41, "column": 10 }, "end": { - "line": 57, + "line": 41, "column": 11 } }, @@ -6268,15 +4490,15 @@ "operator": "<", "right": { "type": "Identifier", - "start": 1816, - "end": 1817, + "start": 1283, + "end": 1284, "loc": { "start": { - "line": 57, + "line": 41, "column": 14 }, "end": { - "line": 57, + "line": 41, "column": 15 } }, @@ -6289,15 +4511,15 @@ }, { "type": "Identifier", - "start": 1820, - "end": 1821, + "start": 1287, + "end": 1288, "loc": { "start": { - "line": 57, + "line": 41, "column": 18 }, "end": { - "line": 57, + "line": 41, "column": 19 } }, @@ -6309,44 +4531,44 @@ }, { "type": "VariableDeclaration", - "start": 2031, - "end": 2062, + "start": 1498, + "end": 1529, "loc": { "start": { - "line": 62, + "line": 46, "column": 1 }, "end": { - "line": 62, + "line": 46, "column": 32 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2037, - "end": 2061, + "start": 1504, + "end": 1528, "loc": { "start": { - "line": 62, + "line": 46, "column": 7 }, "end": { - "line": 62, + "line": 46, "column": 31 } }, "id": { "type": "Identifier", - "start": 2037, - "end": 2040, + "start": 1504, + "end": 1507, "loc": { "start": { - "line": 62, + "line": 46, "column": 7 }, "end": { - "line": 62, + "line": 46, "column": 10 } }, @@ -6354,43 +4576,43 @@ }, "init": { "type": "BinaryExpression", - "start": 2043, - "end": 2061, + "start": 1510, + "end": 1528, "loc": { "start": { - "line": 62, + "line": 46, "column": 13 }, "end": { - "line": 62, + "line": 46, "column": 31 } }, "left": { "type": "BinaryExpression", - "start": 2043, - "end": 2057, + "start": 1510, + "end": 1524, "loc": { "start": { - "line": 62, + "line": 46, "column": 13 }, "end": { - "line": 62, + "line": 46, "column": 27 } }, "left": { "type": "Identifier", - "start": 2043, - "end": 2044, + "start": 1510, + "end": 1511, "loc": { "start": { - "line": 62, + "line": 46, "column": 13 }, "end": { - "line": 62, + "line": 46, "column": 14 } }, @@ -6399,29 +4621,29 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 2047, - "end": 2057, + "start": 1514, + "end": 1524, "loc": { "start": { - "line": 62, + "line": 46, "column": 17 }, "end": { - "line": 62, + "line": 46, "column": 27 } }, "object": { "type": "Identifier", - "start": 2047, - "end": 2050, + "start": 1514, + "end": 1517, "loc": { "start": { - "line": 62, + "line": 46, "column": 17 }, "end": { - "line": 62, + "line": 46, "column": 20 } }, @@ -6429,29 +4651,29 @@ }, "property": { "type": "BinaryExpression", - "start": 2051, - "end": 2056, + "start": 1518, + "end": 1523, "loc": { "start": { - "line": 62, + "line": 46, "column": 21 }, "end": { - "line": 62, + "line": 46, "column": 26 } }, "left": { "type": "Identifier", - "start": 2051, - "end": 2052, + "start": 1518, + "end": 1519, "loc": { "start": { - "line": 62, + "line": 46, "column": 21 }, "end": { - "line": 62, + "line": 46, "column": 22 } }, @@ -6460,15 +4682,15 @@ "operator": "-", "right": { "type": "Literal", - "start": 2055, - "end": 2056, + "start": 1522, + "end": 1523, "loc": { "start": { - "line": 62, + "line": 46, "column": 25 }, "end": { - "line": 62, + "line": 46, "column": 26 } }, @@ -6483,15 +4705,15 @@ "operator": ">", "right": { "type": "Identifier", - "start": 2060, - "end": 2061, + "start": 1527, + "end": 1528, "loc": { "start": { - "line": 62, + "line": 46, "column": 30 }, "end": { - "line": 62, + "line": 46, "column": 31 } }, @@ -6505,63 +4727,63 @@ { "type": "Line", "value": " arithmetic inside the index is not a type, so the list stays a comparison even", - "start": 1826, - "end": 1907 + "start": 1293, + "end": 1374 }, { "type": "Line", "value": " when a `>` closes it; a negated operand and the logical and relational operators", - "start": 1909, - "end": 1992 + "start": 1376, + "end": 1459 }, { "type": "Line", "value": " are expressions too, never types", - "start": 1994, - "end": 2029 + "start": 1461, + "end": 1496 } ] }, { "type": "VariableDeclaration", - "start": 2064, - "end": 2092, + "start": 1531, + "end": 1559, "loc": { "start": { - "line": 63, + "line": 47, "column": 1 }, "end": { - "line": 63, + "line": 47, "column": 29 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2070, - "end": 2091, + "start": 1537, + "end": 1558, "loc": { "start": { - "line": 63, + "line": 47, "column": 7 }, "end": { - "line": 63, + "line": 47, "column": 28 } }, "id": { "type": "Identifier", - "start": 2070, - "end": 2073, + "start": 1537, + "end": 1540, "loc": { "start": { - "line": 63, + "line": 47, "column": 7 }, "end": { - "line": 63, + "line": 47, "column": 10 } }, @@ -6569,43 +4791,43 @@ }, "init": { "type": "BinaryExpression", - "start": 2076, - "end": 2091, + "start": 1543, + "end": 1558, "loc": { "start": { - "line": 63, + "line": 47, "column": 13 }, "end": { - "line": 63, + "line": 47, "column": 28 } }, "left": { "type": "BinaryExpression", - "start": 2076, - "end": 2087, + "start": 1543, + "end": 1554, "loc": { "start": { - "line": 63, + "line": 47, "column": 13 }, "end": { - "line": 63, + "line": 47, "column": 24 } }, "left": { "type": "Identifier", - "start": 2076, - "end": 2077, + "start": 1543, + "end": 1544, "loc": { "start": { - "line": 63, + "line": 47, "column": 13 }, "end": { - "line": 63, + "line": 47, "column": 14 } }, @@ -6614,261 +4836,65 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 2080, - "end": 2087, + "start": 1547, + "end": 1554, "loc": { "start": { - "line": 63, + "line": 47, "column": 17 }, "end": { - "line": 63, + "line": 47, "column": 24 } }, "object": { "type": "Identifier", - "start": 2080, - "end": 2083, - "loc": { - "start": { - "line": 63, - "column": 17 - }, - "end": { - "line": 63, - "column": 20 - } - }, - "name": "arr" - }, - "property": { - "type": "UnaryExpression", - "start": 2084, - "end": 2086, - "loc": { - "start": { - "line": 63, - "column": 21 - }, - "end": { - "line": 63, - "column": 23 - } - }, - "operator": "-", - "prefix": true, - "argument": { - "type": "Identifier", - "start": 2085, - "end": 2086, - "loc": { - "start": { - "line": 63, - "column": 22 - }, - "end": { - "line": 63, - "column": 23 - } - }, - "name": "b" - } - }, - "computed": true, - "optional": false - } - }, - "operator": ">", - "right": { - "type": "Identifier", - "start": 2090, - "end": 2091, - "loc": { - "start": { - "line": 63, - "column": 27 - }, - "end": { - "line": 63, - "column": 28 - } - }, - "name": "c" - } - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "start": 2094, - "end": 2124, - "loc": { - "start": { - "line": 64, - "column": 1 - }, - "end": { - "line": 64, - "column": 31 - } - }, - "declarations": [ - { - "type": "VariableDeclarator", - "start": 2100, - "end": 2123, - "loc": { - "start": { - "line": 64, - "column": 7 - }, - "end": { - "line": 64, - "column": 30 - } - }, - "id": { - "type": "Identifier", - "start": 2100, - "end": 2103, - "loc": { - "start": { - "line": 64, - "column": 7 - }, - "end": { - "line": 64, - "column": 10 - } - }, - "name": "a34" - }, - "init": { - "type": "BinaryExpression", - "start": 2106, - "end": 2123, - "loc": { - "start": { - "line": 64, - "column": 13 - }, - "end": { - "line": 64, - "column": 30 - } - }, - "left": { - "type": "BinaryExpression", - "start": 2106, - "end": 2119, - "loc": { - "start": { - "line": 64, - "column": 13 - }, - "end": { - "line": 64, - "column": 26 - } - }, - "left": { - "type": "Identifier", - "start": 2106, - "end": 2107, - "loc": { - "start": { - "line": 64, - "column": 13 - }, - "end": { - "line": 64, - "column": 14 - } - }, - "name": "a" - }, - "operator": "<", - "right": { - "type": "MemberExpression", - "start": 2110, - "end": 2119, - "loc": { - "start": { - "line": 64, - "column": 17 - }, - "end": { - "line": 64, - "column": 26 - } - }, - "object": { - "type": "Identifier", - "start": 2110, - "end": 2111, + "start": 1547, + "end": 1550, "loc": { "start": { - "line": 64, + "line": 47, "column": 17 }, "end": { - "line": 64, - "column": 18 + "line": 47, + "column": 20 } }, - "name": "B" + "name": "arr" }, "property": { - "type": "LogicalExpression", - "start": 2112, - "end": 2118, + "type": "UnaryExpression", + "start": 1551, + "end": 1553, "loc": { "start": { - "line": 64, - "column": 19 + "line": 47, + "column": 21 }, "end": { - "line": 64, - "column": 25 + "line": 47, + "column": 23 } }, - "left": { - "type": "Literal", - "start": 2112, - "end": 2113, - "loc": { - "start": { - "line": 64, - "column": 19 - }, - "end": { - "line": 64, - "column": 20 - } - }, - "value": 0, - "raw": "0" - }, - "operator": "||", - "right": { - "type": "Literal", - "start": 2117, - "end": 2118, + "operator": "-", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 1552, + "end": 1553, "loc": { "start": { - "line": 64, - "column": 24 + "line": 47, + "column": 22 }, "end": { - "line": 64, - "column": 25 + "line": 47, + "column": 23 } }, - "value": 1, - "raw": "1" + "name": "b" } }, "computed": true, @@ -6878,16 +4904,16 @@ "operator": ">", "right": { "type": "Identifier", - "start": 2122, - "end": 2123, + "start": 1557, + "end": 1558, "loc": { "start": { - "line": 64, - "column": 29 + "line": 47, + "column": 27 }, "end": { - "line": 64, - "column": 30 + "line": 47, + "column": 28 } }, "name": "c" @@ -6899,88 +4925,88 @@ }, { "type": "VariableDeclaration", - "start": 2126, - "end": 2156, + "start": 1561, + "end": 1591, "loc": { "start": { - "line": 65, + "line": 48, "column": 1 }, "end": { - "line": 65, + "line": 48, "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2132, - "end": 2155, + "start": 1567, + "end": 1590, "loc": { "start": { - "line": 65, + "line": 48, "column": 7 }, "end": { - "line": 65, + "line": 48, "column": 30 } }, "id": { "type": "Identifier", - "start": 2132, - "end": 2135, + "start": 1567, + "end": 1570, "loc": { "start": { - "line": 65, + "line": 48, "column": 7 }, "end": { - "line": 65, + "line": 48, "column": 10 } }, - "name": "a35" + "name": "a34" }, "init": { "type": "BinaryExpression", - "start": 2138, - "end": 2155, + "start": 1573, + "end": 1590, "loc": { "start": { - "line": 65, + "line": 48, "column": 13 }, "end": { - "line": 65, + "line": 48, "column": 30 } }, "left": { "type": "BinaryExpression", - "start": 2138, - "end": 2151, + "start": 1573, + "end": 1586, "loc": { "start": { - "line": 65, + "line": 48, "column": 13 }, "end": { - "line": 65, + "line": 48, "column": 26 } }, "left": { "type": "Identifier", - "start": 2138, - "end": 2139, + "start": 1573, + "end": 1574, "loc": { "start": { - "line": 65, + "line": 48, "column": 13 }, "end": { - "line": 65, + "line": 48, "column": 14 } }, @@ -6989,77 +5015,77 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 2142, - "end": 2151, + "start": 1577, + "end": 1586, "loc": { "start": { - "line": 65, + "line": 48, "column": 17 }, "end": { - "line": 65, + "line": 48, "column": 26 } }, "object": { "type": "Identifier", - "start": 2142, - "end": 2143, + "start": 1577, + "end": 1578, "loc": { "start": { - "line": 65, + "line": 48, "column": 17 }, "end": { - "line": 65, + "line": 48, "column": 18 } }, "name": "B" }, "property": { - "type": "BinaryExpression", - "start": 2144, - "end": 2150, + "type": "LogicalExpression", + "start": 1579, + "end": 1585, "loc": { "start": { - "line": 65, + "line": 48, "column": 19 }, "end": { - "line": 65, + "line": 48, "column": 25 } }, "left": { "type": "Literal", - "start": 2144, - "end": 2145, + "start": 1579, + "end": 1580, "loc": { "start": { - "line": 65, + "line": 48, "column": 19 }, "end": { - "line": 65, + "line": 48, "column": 20 } }, "value": 0, "raw": "0" }, - "operator": "<=", + "operator": "||", "right": { "type": "Literal", - "start": 2149, - "end": 2150, + "start": 1584, + "end": 1585, "loc": { "start": { - "line": 65, + "line": 48, "column": 24 }, "end": { - "line": 65, + "line": 48, "column": 25 } }, @@ -7074,15 +5100,15 @@ "operator": ">", "right": { "type": "Identifier", - "start": 2154, - "end": 2155, + "start": 1589, + "end": 1590, "loc": { "start": { - "line": 65, + "line": 48, "column": 29 }, "end": { - "line": 65, + "line": 48, "column": 30 } }, @@ -7095,88 +5121,88 @@ }, { "type": "VariableDeclaration", - "start": 2318, - "end": 2343, + "start": 1593, + "end": 1623, "loc": { "start": { - "line": 69, + "line": 49, "column": 1 }, "end": { - "line": 69, - "column": 26 + "line": 49, + "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2324, - "end": 2342, + "start": 1599, + "end": 1622, "loc": { "start": { - "line": 69, + "line": 49, "column": 7 }, "end": { - "line": 69, - "column": 25 + "line": 49, + "column": 30 } }, "id": { "type": "Identifier", - "start": 2324, - "end": 2327, + "start": 1599, + "end": 1602, "loc": { "start": { - "line": 69, + "line": 49, "column": 7 }, "end": { - "line": 69, + "line": 49, "column": 10 } }, - "name": "a28" + "name": "a35" }, "init": { "type": "BinaryExpression", - "start": 2330, - "end": 2342, + "start": 1605, + "end": 1622, "loc": { "start": { - "line": 69, + "line": 49, "column": 13 }, "end": { - "line": 69, - "column": 25 + "line": 49, + "column": 30 } }, "left": { "type": "BinaryExpression", - "start": 2330, - "end": 2338, + "start": 1605, + "end": 1618, "loc": { "start": { - "line": 69, + "line": 49, "column": 13 }, "end": { - "line": 69, - "column": 21 + "line": 49, + "column": 26 } }, "left": { "type": "Identifier", - "start": 2330, - "end": 2331, + "start": 1605, + "end": 1606, "loc": { "start": { - "line": 69, + "line": 49, "column": 13 }, "end": { - "line": 69, + "line": 49, "column": 14 } }, @@ -7185,49 +5211,83 @@ "operator": "<", "right": { "type": "MemberExpression", - "start": 2334, - "end": 2338, + "start": 1609, + "end": 1618, "loc": { "start": { - "line": 69, + "line": 49, "column": 17 }, "end": { - "line": 69, - "column": 21 + "line": 49, + "column": 26 } }, "object": { "type": "Identifier", - "start": 2334, - "end": 2335, + "start": 1609, + "end": 1610, "loc": { "start": { - "line": 69, + "line": 49, "column": 17 }, "end": { - "line": 69, + "line": 49, "column": 18 } }, "name": "B" }, "property": { - "type": "Identifier", - "start": 2336, - "end": 2337, + "type": "BinaryExpression", + "start": 1611, + "end": 1617, "loc": { "start": { - "line": 69, + "line": 49, "column": 19 }, "end": { - "line": 69, - "column": 20 + "line": 49, + "column": 25 } }, - "name": "c" + "left": { + "type": "Literal", + "start": 1611, + "end": 1612, + "loc": { + "start": { + "line": 49, + "column": 19 + }, + "end": { + "line": 49, + "column": 20 + } + }, + "value": 0, + "raw": "0" + }, + "operator": "<=", + "right": { + "type": "Literal", + "start": 1616, + "end": 1617, + "loc": { + "start": { + "line": 49, + "column": 24 + }, + "end": { + "line": 49, + "column": 25 + } + }, + "value": 1, + "raw": "1" + } }, "computed": true, "optional": false @@ -7236,79 +5296,65 @@ "operator": ">", "right": { "type": "Identifier", - "start": 2341, - "end": 2342, + "start": 1621, + "end": 1622, "loc": { "start": { - "line": 69, - "column": 24 + "line": 49, + "column": 29 }, "end": { - "line": 69, - "column": 25 + "line": 49, + "column": 30 } }, - "name": "d" + "name": "c" } } } ], - "kind": "const", - "leadingComments": [ - { - "type": "Line", - "value": " a `>` or a shift operator after the indexed operand continues the comparison", - "start": 2159, - "end": 2238 - }, - { - "type": "Line", - "value": " chain — the `>` run belongs to the operator, not to a type-argument close", - "start": 2240, - "end": 2316 - } - ] + "kind": "const" }, { "type": "VariableDeclaration", - "start": 2345, - "end": 2371, + "start": 1776, + "end": 1802, "loc": { "start": { - "line": 70, + "line": 53, "column": 1 }, "end": { - "line": 70, + "line": 53, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2351, - "end": 2370, + "start": 1782, + "end": 1801, "loc": { "start": { - "line": 70, + "line": 53, "column": 7 }, "end": { - "line": 70, + "line": 53, "column": 26 } }, "id": { "type": "Identifier", - "start": 2351, - "end": 2354, + "start": 1782, + "end": 1785, "loc": { "start": { - "line": 70, + "line": 53, "column": 7 }, "end": { - "line": 70, + "line": 53, "column": 10 } }, @@ -7316,29 +5362,29 @@ }, "init": { "type": "BinaryExpression", - "start": 2357, - "end": 2370, + "start": 1788, + "end": 1801, "loc": { "start": { - "line": 70, + "line": 53, "column": 13 }, "end": { - "line": 70, + "line": 53, "column": 26 } }, "left": { "type": "Identifier", - "start": 2357, - "end": 2358, + "start": 1788, + "end": 1789, "loc": { "start": { - "line": 70, + "line": 53, "column": 13 }, "end": { - "line": 70, + "line": 53, "column": 14 } }, @@ -7347,43 +5393,43 @@ "operator": "<", "right": { "type": "BinaryExpression", - "start": 2361, - "end": 2370, + "start": 1792, + "end": 1801, "loc": { "start": { - "line": 70, + "line": 53, "column": 17 }, "end": { - "line": 70, + "line": 53, "column": 26 } }, "left": { "type": "MemberExpression", - "start": 2361, - "end": 2365, + "start": 1792, + "end": 1796, "loc": { "start": { - "line": 70, + "line": 53, "column": 17 }, "end": { - "line": 70, + "line": 53, "column": 21 } }, "object": { "type": "Identifier", - "start": 2361, - "end": 2362, + "start": 1792, + "end": 1793, "loc": { "start": { - "line": 70, + "line": 53, "column": 17 }, "end": { - "line": 70, + "line": 53, "column": 18 } }, @@ -7391,15 +5437,15 @@ }, "property": { "type": "Identifier", - "start": 2363, - "end": 2364, + "start": 1794, + "end": 1795, "loc": { "start": { - "line": 70, + "line": 53, "column": 19 }, "end": { - "line": 70, + "line": 53, "column": 20 } }, @@ -7411,15 +5457,15 @@ "operator": ">>", "right": { "type": "Identifier", - "start": 2369, - "end": 2370, + "start": 1800, + "end": 1801, "loc": { "start": { - "line": 70, + "line": 53, "column": 25 }, "end": { - "line": 70, + "line": 53, "column": 26 } }, @@ -7429,48 +5475,62 @@ } } ], - "kind": "const" + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " a shift operator after the indexed operand continues the comparison chain — the", + "start": 1626, + "end": 1708 + }, + { + "type": "Line", + "value": " `>` run belongs to the operator, not to a type-argument close", + "start": 1710, + "end": 1774 + } + ] }, { "type": "VariableDeclaration", - "start": 2373, - "end": 2400, + "start": 1804, + "end": 1831, "loc": { "start": { - "line": 71, + "line": 54, "column": 1 }, "end": { - "line": 71, + "line": 54, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2379, - "end": 2399, + "start": 1810, + "end": 1830, "loc": { "start": { - "line": 71, + "line": 54, "column": 7 }, "end": { - "line": 71, + "line": 54, "column": 27 } }, "id": { "type": "Identifier", - "start": 2379, - "end": 2382, + "start": 1810, + "end": 1813, "loc": { "start": { - "line": 71, + "line": 54, "column": 7 }, "end": { - "line": 71, + "line": 54, "column": 10 } }, @@ -7478,29 +5538,29 @@ }, "init": { "type": "BinaryExpression", - "start": 2385, - "end": 2399, + "start": 1816, + "end": 1830, "loc": { "start": { - "line": 71, + "line": 54, "column": 13 }, "end": { - "line": 71, + "line": 54, "column": 27 } }, "left": { "type": "Identifier", - "start": 2385, - "end": 2386, + "start": 1816, + "end": 1817, "loc": { "start": { - "line": 71, + "line": 54, "column": 13 }, "end": { - "line": 71, + "line": 54, "column": 14 } }, @@ -7509,43 +5569,43 @@ "operator": "<", "right": { "type": "BinaryExpression", - "start": 2389, - "end": 2399, + "start": 1820, + "end": 1830, "loc": { "start": { - "line": 71, + "line": 54, "column": 17 }, "end": { - "line": 71, + "line": 54, "column": 27 } }, "left": { "type": "MemberExpression", - "start": 2389, - "end": 2393, + "start": 1820, + "end": 1824, "loc": { "start": { - "line": 71, + "line": 54, "column": 17 }, "end": { - "line": 71, + "line": 54, "column": 21 } }, "object": { "type": "Identifier", - "start": 2389, - "end": 2390, + "start": 1820, + "end": 1821, "loc": { "start": { - "line": 71, + "line": 54, "column": 17 }, "end": { - "line": 71, + "line": 54, "column": 18 } }, @@ -7553,15 +5613,15 @@ }, "property": { "type": "Identifier", - "start": 2391, - "end": 2392, + "start": 1822, + "end": 1823, "loc": { "start": { - "line": 71, + "line": 54, "column": 19 }, "end": { - "line": 71, + "line": 54, "column": 20 } }, @@ -7573,15 +5633,15 @@ "operator": ">>>", "right": { "type": "Identifier", - "start": 2398, - "end": 2399, + "start": 1829, + "end": 1830, "loc": { "start": { - "line": 71, + "line": 54, "column": 26 }, "end": { - "line": 71, + "line": 54, "column": 27 } }, @@ -7595,44 +5655,44 @@ }, { "type": "VariableDeclaration", - "start": 2526, - "end": 2544, + "start": 1957, + "end": 1975, "loc": { "start": { - "line": 75, + "line": 58, "column": 1 }, "end": { - "line": 75, + "line": 58, "column": 19 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2532, - "end": 2543, + "start": 1963, + "end": 1974, "loc": { "start": { - "line": 75, + "line": 58, "column": 7 }, "end": { - "line": 75, + "line": 58, "column": 18 } }, "id": { "type": "Identifier", - "start": 2532, - "end": 2535, + "start": 1963, + "end": 1966, "loc": { "start": { - "line": 75, + "line": 58, "column": 7 }, "end": { - "line": 75, + "line": 58, "column": 10 } }, @@ -7640,29 +5700,29 @@ }, "init": { "type": "BinaryExpression", - "start": 2538, - "end": 2543, + "start": 1969, + "end": 1974, "loc": { "start": { - "line": 75, + "line": 58, "column": 13 }, "end": { - "line": 75, + "line": 58, "column": 18 } }, "left": { "type": "Identifier", - "start": 2538, - "end": 2539, + "start": 1969, + "end": 1970, "loc": { "start": { - "line": 75, + "line": 58, "column": 13 }, "end": { - "line": 75, + "line": 58, "column": 14 } }, @@ -7671,15 +5731,15 @@ "operator": "<", "right": { "type": "Identifier", - "start": 2542, - "end": 2543, + "start": 1973, + "end": 1974, "loc": { "start": { - "line": 75, + "line": 58, "column": 17 }, "end": { - "line": 75, + "line": 58, "column": 18 } }, @@ -7693,56 +5753,56 @@ { "type": "Line", "value": " an identifier that merely starts with `extends` is a fresh statement on the next", - "start": 2403, - "end": 2486 + "start": 1834, + "end": 1917 }, { "type": "Line", "value": " line (ASI), not a type constraint", - "start": 2488, - "end": 2524 + "start": 1919, + "end": 1955 } ] }, { "type": "ExpressionStatement", - "start": 2546, - "end": 2559, + "start": 1977, + "end": 1990, "loc": { "start": { - "line": 76, + "line": 59, "column": 1 }, "end": { - "line": 76, + "line": 59, "column": 14 } }, "expression": { "type": "CallExpression", - "start": 2546, - "end": 2558, + "start": 1977, + "end": 1989, "loc": { "start": { - "line": 76, + "line": 59, "column": 1 }, "end": { - "line": 76, + "line": 59, "column": 13 } }, "callee": { "type": "Identifier", - "start": 2546, - "end": 2556, + "start": 1977, + "end": 1987, "loc": { "start": { - "line": 76, + "line": 59, "column": 1 }, "end": { - "line": 76, + "line": 59, "column": 11 } }, @@ -7754,44 +5814,44 @@ }, { "type": "VariableDeclaration", - "start": 2720, - "end": 2741, + "start": 2151, + "end": 2172, "loc": { "start": { - "line": 80, + "line": 63, "column": 1 }, "end": { - "line": 80, + "line": 63, "column": 22 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2726, - "end": 2740, + "start": 2157, + "end": 2171, "loc": { "start": { - "line": 80, + "line": 63, "column": 7 }, "end": { - "line": 80, + "line": 63, "column": 21 } }, "id": { "type": "Identifier", - "start": 2726, - "end": 2728, + "start": 2157, + "end": 2159, "loc": { "start": { - "line": 80, + "line": 63, "column": 7 }, "end": { - "line": 80, + "line": 63, "column": 9 } }, @@ -7799,29 +5859,29 @@ }, "init": { "type": "CallExpression", - "start": 2731, - "end": 2740, + "start": 2162, + "end": 2171, "loc": { "start": { - "line": 80, + "line": 63, "column": 12 }, "end": { - "line": 80, + "line": 63, "column": 21 } }, "callee": { "type": "Identifier", - "start": 2731, - "end": 2733, + "start": 2162, + "end": 2164, "loc": { "start": { - "line": 80, + "line": 63, "column": 12 }, "end": { - "line": 80, + "line": 63, "column": 14 } }, @@ -7830,44 +5890,44 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2733, - "end": 2738, + "start": 2164, + "end": 2169, "loc": { "start": { - "line": 80, + "line": 63, "column": 14 }, "end": { - "line": 80, + "line": 63, "column": 19 } }, "params": [ { "type": "TSLiteralType", - "start": 2734, - "end": 2737, + "start": 2165, + "end": 2168, "loc": { "start": { - "line": 80, + "line": 63, "column": 15 }, "end": { - "line": 80, + "line": 63, "column": 18 } }, "literal": { "type": "Literal", - "start": 2734, - "end": 2737, + "start": 2165, + "end": 2168, "loc": { "start": { - "line": 80, + "line": 63, "column": 15 }, "end": { - "line": 80, + "line": 63, "column": 18 } }, @@ -7885,57 +5945,57 @@ { "type": "Line", "value": " genuine instantiation with a literal/keyword/object/tuple/numeric type arg, or a", - "start": 2562, - "end": 2645 + "start": 1993, + "end": 2076 }, { "type": "Line", "value": " function type with an optional param, still parses as type arguments", - "start": 2647, - "end": 2718 + "start": 2078, + "end": 2149 } ] }, { "type": "VariableDeclaration", - "start": 2743, - "end": 2765, + "start": 2174, + "end": 2196, "loc": { "start": { - "line": 81, + "line": 64, "column": 1 }, "end": { - "line": 81, + "line": 64, "column": 23 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2749, - "end": 2764, + "start": 2180, + "end": 2195, "loc": { "start": { - "line": 81, + "line": 64, "column": 7 }, "end": { - "line": 81, + "line": 64, "column": 22 } }, "id": { "type": "Identifier", - "start": 2749, - "end": 2751, + "start": 2180, + "end": 2182, "loc": { "start": { - "line": 81, + "line": 64, "column": 7 }, "end": { - "line": 81, + "line": 64, "column": 9 } }, @@ -7943,29 +6003,29 @@ }, "init": { "type": "CallExpression", - "start": 2754, - "end": 2764, + "start": 2185, + "end": 2195, "loc": { "start": { - "line": 81, + "line": 64, "column": 12 }, "end": { - "line": 81, + "line": 64, "column": 22 } }, "callee": { "type": "Identifier", - "start": 2754, - "end": 2756, + "start": 2185, + "end": 2187, "loc": { "start": { - "line": 81, + "line": 64, "column": 12 }, "end": { - "line": 81, + "line": 64, "column": 14 } }, @@ -7974,44 +6034,44 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2756, - "end": 2762, + "start": 2187, + "end": 2193, "loc": { "start": { - "line": 81, + "line": 64, "column": 14 }, "end": { - "line": 81, + "line": 64, "column": 20 } }, "params": [ { "type": "TSLiteralType", - "start": 2757, - "end": 2761, + "start": 2188, + "end": 2192, "loc": { "start": { - "line": 81, + "line": 64, "column": 15 }, "end": { - "line": 81, + "line": 64, "column": 19 } }, "literal": { "type": "Literal", - "start": 2757, - "end": 2761, + "start": 2188, + "end": 2192, "loc": { "start": { - "line": 81, + "line": 64, "column": 15 }, "end": { - "line": 81, + "line": 64, "column": 19 } }, @@ -8028,44 +6088,44 @@ }, { "type": "VariableDeclaration", - "start": 2767, - "end": 2791, + "start": 2198, + "end": 2222, "loc": { "start": { - "line": 82, + "line": 65, "column": 1 }, "end": { - "line": 82, + "line": 65, "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2773, - "end": 2790, + "start": 2204, + "end": 2221, "loc": { "start": { - "line": 82, + "line": 65, "column": 7 }, "end": { - "line": 82, + "line": 65, "column": 24 } }, "id": { "type": "Identifier", - "start": 2773, - "end": 2775, + "start": 2204, + "end": 2206, "loc": { "start": { - "line": 82, + "line": 65, "column": 7 }, "end": { - "line": 82, + "line": 65, "column": 9 } }, @@ -8073,29 +6133,29 @@ }, "init": { "type": "CallExpression", - "start": 2778, - "end": 2790, + "start": 2209, + "end": 2221, "loc": { "start": { - "line": 82, + "line": 65, "column": 12 }, "end": { - "line": 82, + "line": 65, "column": 24 } }, "callee": { "type": "Identifier", - "start": 2778, - "end": 2780, + "start": 2209, + "end": 2211, "loc": { "start": { - "line": 82, + "line": 65, "column": 12 }, "end": { - "line": 82, + "line": 65, "column": 14 } }, @@ -8104,30 +6164,30 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2780, - "end": 2788, + "start": 2211, + "end": 2219, "loc": { "start": { - "line": 82, + "line": 65, "column": 14 }, "end": { - "line": 82, + "line": 65, "column": 22 } }, "params": [ { "type": "TSStringKeyword", - "start": 2781, - "end": 2787, + "start": 2212, + "end": 2218, "loc": { "start": { - "line": 82, + "line": 65, "column": 15 }, "end": { - "line": 82, + "line": 65, "column": 21 } } @@ -8141,44 +6201,44 @@ }, { "type": "VariableDeclaration", - "start": 2793, - "end": 2824, + "start": 2224, + "end": 2255, "loc": { "start": { - "line": 83, + "line": 66, "column": 1 }, "end": { - "line": 83, + "line": 66, "column": 32 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2799, - "end": 2823, + "start": 2230, + "end": 2254, "loc": { "start": { - "line": 83, + "line": 66, "column": 7 }, "end": { - "line": 83, + "line": 66, "column": 31 } }, "id": { "type": "Identifier", - "start": 2799, - "end": 2801, + "start": 2230, + "end": 2232, "loc": { "start": { - "line": 83, + "line": 66, "column": 7 }, "end": { - "line": 83, + "line": 66, "column": 9 } }, @@ -8186,29 +6246,29 @@ }, "init": { "type": "CallExpression", - "start": 2804, - "end": 2823, + "start": 2235, + "end": 2254, "loc": { "start": { - "line": 83, + "line": 66, "column": 12 }, "end": { - "line": 83, + "line": 66, "column": 31 } }, "callee": { "type": "Identifier", - "start": 2804, - "end": 2806, + "start": 2235, + "end": 2237, "loc": { "start": { - "line": 83, + "line": 66, "column": 12 }, "end": { - "line": 83, + "line": 66, "column": 14 } }, @@ -8217,60 +6277,60 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2806, - "end": 2821, + "start": 2237, + "end": 2252, "loc": { "start": { - "line": 83, + "line": 66, "column": 14 }, "end": { - "line": 83, + "line": 66, "column": 29 } }, "params": [ { "type": "TSTypeLiteral", - "start": 2807, - "end": 2820, + "start": 2238, + "end": 2251, "loc": { "start": { - "line": 83, + "line": 66, "column": 15 }, "end": { - "line": 83, + "line": 66, "column": 28 } }, "members": [ { "type": "TSPropertySignature", - "start": 2809, - "end": 2818, + "start": 2240, + "end": 2249, "loc": { "start": { - "line": 83, + "line": 66, "column": 17 }, "end": { - "line": 83, + "line": 66, "column": 26 } }, "computed": false, "key": { "type": "Identifier", - "start": 2809, - "end": 2810, + "start": 2240, + "end": 2241, "loc": { "start": { - "line": 83, + "line": 66, "column": 17 }, "end": { - "line": 83, + "line": 66, "column": 18 } }, @@ -8278,29 +6338,29 @@ }, "typeAnnotation": { "type": "TSTypeAnnotation", - "start": 2810, - "end": 2818, + "start": 2241, + "end": 2249, "loc": { "start": { - "line": 83, + "line": 66, "column": 18 }, "end": { - "line": 83, + "line": 66, "column": 26 } }, "typeAnnotation": { "type": "TSNumberKeyword", - "start": 2812, - "end": 2818, + "start": 2243, + "end": 2249, "loc": { "start": { - "line": 83, + "line": 66, "column": 20 }, "end": { - "line": 83, + "line": 66, "column": 26 } } @@ -8318,44 +6378,44 @@ }, { "type": "VariableDeclaration", - "start": 2826, - "end": 2850, + "start": 2257, + "end": 2281, "loc": { "start": { - "line": 84, + "line": 67, "column": 1 }, "end": { - "line": 84, + "line": 67, "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2832, - "end": 2849, + "start": 2263, + "end": 2280, "loc": { "start": { - "line": 84, + "line": 67, "column": 7 }, "end": { - "line": 84, + "line": 67, "column": 24 } }, "id": { "type": "Identifier", - "start": 2832, - "end": 2834, + "start": 2263, + "end": 2265, "loc": { "start": { - "line": 84, + "line": 67, "column": 7 }, "end": { - "line": 84, + "line": 67, "column": 9 } }, @@ -8363,29 +6423,29 @@ }, "init": { "type": "CallExpression", - "start": 2837, - "end": 2849, + "start": 2268, + "end": 2280, "loc": { "start": { - "line": 84, + "line": 67, "column": 12 }, "end": { - "line": 84, + "line": 67, "column": 24 } }, "callee": { "type": "Identifier", - "start": 2837, - "end": 2839, + "start": 2268, + "end": 2270, "loc": { "start": { - "line": 84, + "line": 67, "column": 12 }, "end": { - "line": 84, + "line": 67, "column": 14 } }, @@ -8394,59 +6454,59 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2839, - "end": 2847, + "start": 2270, + "end": 2278, "loc": { "start": { - "line": 84, + "line": 67, "column": 14 }, "end": { - "line": 84, + "line": 67, "column": 22 } }, "params": [ { "type": "TSTupleType", - "start": 2840, - "end": 2846, + "start": 2271, + "end": 2277, "loc": { "start": { - "line": 84, + "line": 67, "column": 15 }, "end": { - "line": 84, + "line": 67, "column": 21 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 2841, - "end": 2842, + "start": 2272, + "end": 2273, "loc": { "start": { - "line": 84, + "line": 67, "column": 16 }, "end": { - "line": 84, + "line": 67, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 2841, - "end": 2842, + "start": 2272, + "end": 2273, "loc": { "start": { - "line": 84, + "line": 67, "column": 16 }, "end": { - "line": 84, + "line": 67, "column": 17 } }, @@ -8455,29 +6515,29 @@ }, { "type": "TSTypeReference", - "start": 2844, - "end": 2845, + "start": 2275, + "end": 2276, "loc": { "start": { - "line": 84, + "line": 67, "column": 19 }, "end": { - "line": 84, + "line": 67, "column": 20 } }, "typeName": { "type": "Identifier", - "start": 2844, - "end": 2845, + "start": 2275, + "end": 2276, "loc": { "start": { - "line": 84, + "line": 67, "column": 19 }, "end": { - "line": 84, + "line": 67, "column": 20 } }, @@ -8495,44 +6555,44 @@ }, { "type": "VariableDeclaration", - "start": 2852, - "end": 2871, + "start": 2283, + "end": 2302, "loc": { "start": { - "line": 85, + "line": 68, "column": 1 }, "end": { - "line": 85, + "line": 68, "column": 20 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2858, - "end": 2870, + "start": 2289, + "end": 2301, "loc": { "start": { - "line": 85, + "line": 68, "column": 7 }, "end": { - "line": 85, + "line": 68, "column": 19 } }, "id": { "type": "Identifier", - "start": 2858, - "end": 2860, + "start": 2289, + "end": 2291, "loc": { "start": { - "line": 85, + "line": 68, "column": 7 }, "end": { - "line": 85, + "line": 68, "column": 9 } }, @@ -8540,29 +6600,29 @@ }, "init": { "type": "CallExpression", - "start": 2863, - "end": 2870, + "start": 2294, + "end": 2301, "loc": { "start": { - "line": 85, + "line": 68, "column": 12 }, "end": { - "line": 85, + "line": 68, "column": 19 } }, "callee": { "type": "Identifier", - "start": 2863, - "end": 2865, + "start": 2294, + "end": 2296, "loc": { "start": { - "line": 85, + "line": 68, "column": 12 }, "end": { - "line": 85, + "line": 68, "column": 14 } }, @@ -8571,44 +6631,44 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2865, - "end": 2868, + "start": 2296, + "end": 2299, "loc": { "start": { - "line": 85, + "line": 68, "column": 14 }, "end": { - "line": 85, + "line": 68, "column": 17 } }, "params": [ { "type": "TSLiteralType", - "start": 2866, - "end": 2867, + "start": 2297, + "end": 2298, "loc": { "start": { - "line": 85, + "line": 68, "column": 15 }, "end": { - "line": 85, + "line": 68, "column": 16 } }, "literal": { "type": "Literal", - "start": 2866, - "end": 2867, + "start": 2297, + "end": 2298, "loc": { "start": { - "line": 85, + "line": 68, "column": 15 }, "end": { - "line": 85, + "line": 68, "column": 16 } }, @@ -8625,44 +6685,44 @@ }, { "type": "VariableDeclaration", - "start": 2873, - "end": 2903, + "start": 2304, + "end": 2334, "loc": { "start": { - "line": 86, + "line": 69, "column": 1 }, "end": { - "line": 86, + "line": 69, "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2879, - "end": 2902, + "start": 2310, + "end": 2333, "loc": { "start": { - "line": 86, + "line": 69, "column": 7 }, "end": { - "line": 86, + "line": 69, "column": 30 } }, "id": { "type": "Identifier", - "start": 2879, - "end": 2881, + "start": 2310, + "end": 2312, "loc": { "start": { - "line": 86, + "line": 69, "column": 7 }, "end": { - "line": 86, + "line": 69, "column": 9 } }, @@ -8670,29 +6730,29 @@ }, "init": { "type": "CallExpression", - "start": 2884, - "end": 2902, + "start": 2315, + "end": 2333, "loc": { "start": { - "line": 86, + "line": 69, "column": 12 }, "end": { - "line": 86, + "line": 69, "column": 30 } }, "callee": { "type": "Identifier", - "start": 2884, - "end": 2886, + "start": 2315, + "end": 2317, "loc": { "start": { - "line": 86, + "line": 69, "column": 12 }, "end": { - "line": 86, + "line": 69, "column": 14 } }, @@ -8701,45 +6761,45 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 2886, - "end": 2900, + "start": 2317, + "end": 2331, "loc": { "start": { - "line": 86, + "line": 69, "column": 14 }, "end": { - "line": 86, + "line": 69, "column": 28 } }, "params": [ { "type": "TSFunctionType", - "start": 2887, - "end": 2899, + "start": 2318, + "end": 2330, "loc": { "start": { - "line": 86, + "line": 69, "column": 15 }, "end": { - "line": 86, + "line": 69, "column": 27 } }, "parameters": [ { "type": "Identifier", - "start": 2888, - "end": 2893, + "start": 2319, + "end": 2324, "loc": { "start": { - "line": 86, + "line": 69, "column": 16 }, "end": { - "line": 86, + "line": 69, "column": 21 } }, @@ -8747,43 +6807,43 @@ "optional": true, "typeAnnotation": { "type": "TSTypeAnnotation", - "start": 2890, - "end": 2893, + "start": 2321, + "end": 2324, "loc": { "start": { - "line": 86, + "line": 69, "column": 18 }, "end": { - "line": 86, + "line": 69, "column": 21 } }, "typeAnnotation": { "type": "TSTypeReference", - "start": 2892, - "end": 2893, + "start": 2323, + "end": 2324, "loc": { "start": { - "line": 86, + "line": 69, "column": 20 }, "end": { - "line": 86, + "line": 69, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 2892, - "end": 2893, + "start": 2323, + "end": 2324, "loc": { "start": { - "line": 86, + "line": 69, "column": 20 }, "end": { - "line": 86, + "line": 69, "column": 21 } }, @@ -8795,43 +6855,43 @@ ], "typeAnnotation": { "type": "TSTypeAnnotation", - "start": 2895, - "end": 2899, + "start": 2326, + "end": 2330, "loc": { "start": { - "line": 86, + "line": 69, "column": 23 }, "end": { - "line": 86, + "line": 69, "column": 27 } }, "typeAnnotation": { "type": "TSTypeReference", - "start": 2898, - "end": 2899, + "start": 2329, + "end": 2330, "loc": { "start": { - "line": 86, + "line": 69, "column": 26 }, "end": { - "line": 86, + "line": 69, "column": 27 } }, "typeName": { "type": "Identifier", - "start": 2898, - "end": 2899, + "start": 2329, + "end": 2330, "loc": { "start": { - "line": 86, + "line": 69, "column": 26 }, "end": { - "line": 86, + "line": 69, "column": 27 } }, @@ -8849,44 +6909,44 @@ }, { "type": "VariableDeclaration", - "start": 2992, - "end": 3016, + "start": 2423, + "end": 2447, "loc": { "start": { - "line": 89, + "line": 72, "column": 1 }, "end": { - "line": 89, + "line": 72, "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 2998, - "end": 3015, + "start": 2429, + "end": 2446, "loc": { "start": { - "line": 89, + "line": 72, "column": 7 }, "end": { - "line": 89, + "line": 72, "column": 24 } }, "id": { "type": "Identifier", - "start": 2998, - "end": 3000, + "start": 2429, + "end": 2431, "loc": { "start": { - "line": 89, + "line": 72, "column": 7 }, "end": { - "line": 89, + "line": 72, "column": 9 } }, @@ -8894,29 +6954,29 @@ }, "init": { "type": "CallExpression", - "start": 3003, - "end": 3015, + "start": 2434, + "end": 2446, "loc": { "start": { - "line": 89, + "line": 72, "column": 12 }, "end": { - "line": 89, + "line": 72, "column": 24 } }, "callee": { "type": "Identifier", - "start": 3003, - "end": 3005, + "start": 2434, + "end": 2436, "loc": { "start": { - "line": 89, + "line": 72, "column": 12 }, "end": { - "line": 89, + "line": 72, "column": 14 } }, @@ -8925,59 +6985,59 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3005, - "end": 3013, + "start": 2436, + "end": 2444, "loc": { "start": { - "line": 89, + "line": 72, "column": 14 }, "end": { - "line": 89, + "line": 72, "column": 22 } }, "params": [ { "type": "TSTupleType", - "start": 3006, - "end": 3012, + "start": 2437, + "end": 2443, "loc": { "start": { - "line": 89, + "line": 72, "column": 15 }, "end": { - "line": 89, + "line": 72, "column": 21 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 3007, - "end": 3011, + "start": 2438, + "end": 2442, "loc": { "start": { - "line": 89, + "line": 72, "column": 16 }, "end": { - "line": 89, + "line": 72, "column": 20 } }, "typeName": { "type": "Identifier", - "start": 3007, - "end": 3008, + "start": 2438, + "end": 2439, "loc": { "start": { - "line": 89, + "line": 72, "column": 16 }, "end": { - "line": 89, + "line": 72, "column": 17 } }, @@ -8985,44 +7045,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3008, - "end": 3011, + "start": 2439, + "end": 2442, "loc": { "start": { - "line": 89, + "line": 72, "column": 17 }, "end": { - "line": 89, + "line": 72, "column": 20 } }, "params": [ { "type": "TSTypeReference", - "start": 3009, - "end": 3010, + "start": 2440, + "end": 2441, "loc": { "start": { - "line": 89, + "line": 72, "column": 18 }, "end": { - "line": 89, + "line": 72, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3009, - "end": 3010, + "start": 2440, + "end": 2441, "loc": { "start": { - "line": 89, + "line": 72, "column": 18 }, "end": { - "line": 89, + "line": 72, "column": 19 } }, @@ -9044,51 +7104,51 @@ { "type": "Line", "value": " a generic nested inside a tuple or object-type arg still parses as type arguments", - "start": 2906, - "end": 2990 + "start": 2337, + "end": 2421 } ] }, { "type": "VariableDeclaration", - "start": 3018, - "end": 3045, + "start": 2449, + "end": 2476, "loc": { "start": { - "line": 90, + "line": 73, "column": 1 }, "end": { - "line": 90, + "line": 73, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3024, - "end": 3044, + "start": 2455, + "end": 2475, "loc": { "start": { - "line": 90, + "line": 73, "column": 7 }, "end": { - "line": 90, + "line": 73, "column": 27 } }, "id": { "type": "Identifier", - "start": 3024, - "end": 3026, + "start": 2455, + "end": 2457, "loc": { "start": { - "line": 90, + "line": 73, "column": 7 }, "end": { - "line": 90, + "line": 73, "column": 9 } }, @@ -9096,29 +7156,29 @@ }, "init": { "type": "CallExpression", - "start": 3029, - "end": 3044, + "start": 2460, + "end": 2475, "loc": { "start": { - "line": 90, + "line": 73, "column": 12 }, "end": { - "line": 90, + "line": 73, "column": 27 } }, "callee": { "type": "Identifier", - "start": 3029, - "end": 3031, + "start": 2460, + "end": 2462, "loc": { "start": { - "line": 90, + "line": 73, "column": 12 }, "end": { - "line": 90, + "line": 73, "column": 14 } }, @@ -9127,59 +7187,59 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3031, - "end": 3042, + "start": 2462, + "end": 2473, "loc": { "start": { - "line": 90, + "line": 73, "column": 14 }, "end": { - "line": 90, + "line": 73, "column": 25 } }, "params": [ { "type": "TSTupleType", - "start": 3032, - "end": 3041, + "start": 2463, + "end": 2472, "loc": { "start": { - "line": 90, + "line": 73, "column": 15 }, "end": { - "line": 90, + "line": 73, "column": 24 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 3033, - "end": 3034, + "start": 2464, + "end": 2465, "loc": { "start": { - "line": 90, + "line": 73, "column": 16 }, "end": { - "line": 90, + "line": 73, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3033, - "end": 3034, + "start": 2464, + "end": 2465, "loc": { "start": { - "line": 90, + "line": 73, "column": 16 }, "end": { - "line": 90, + "line": 73, "column": 17 } }, @@ -9188,29 +7248,29 @@ }, { "type": "TSTypeReference", - "start": 3036, - "end": 3040, + "start": 2467, + "end": 2471, "loc": { "start": { - "line": 90, + "line": 73, "column": 19 }, "end": { - "line": 90, + "line": 73, "column": 23 } }, "typeName": { "type": "Identifier", - "start": 3036, - "end": 3037, + "start": 2467, + "end": 2468, "loc": { "start": { - "line": 90, + "line": 73, "column": 19 }, "end": { - "line": 90, + "line": 73, "column": 20 } }, @@ -9218,44 +7278,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3037, - "end": 3040, + "start": 2468, + "end": 2471, "loc": { "start": { - "line": 90, + "line": 73, "column": 20 }, "end": { - "line": 90, + "line": 73, "column": 23 } }, "params": [ { "type": "TSTypeReference", - "start": 3038, - "end": 3039, + "start": 2469, + "end": 2470, "loc": { "start": { - "line": 90, + "line": 73, "column": 21 }, "end": { - "line": 90, + "line": 73, "column": 22 } }, "typeName": { "type": "Identifier", - "start": 3038, - "end": 3039, + "start": 2469, + "end": 2470, "loc": { "start": { - "line": 90, + "line": 73, "column": 21 }, "end": { - "line": 90, + "line": 73, "column": 22 } }, @@ -9276,44 +7336,44 @@ }, { "type": "VariableDeclaration", - "start": 3047, - "end": 3077, + "start": 2478, + "end": 2508, "loc": { "start": { - "line": 91, + "line": 74, "column": 1 }, "end": { - "line": 91, + "line": 74, "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3053, - "end": 3076, + "start": 2484, + "end": 2507, "loc": { "start": { - "line": 91, + "line": 74, "column": 7 }, "end": { - "line": 91, + "line": 74, "column": 30 } }, "id": { "type": "Identifier", - "start": 3053, - "end": 3056, + "start": 2484, + "end": 2487, "loc": { "start": { - "line": 91, + "line": 74, "column": 7 }, "end": { - "line": 91, + "line": 74, "column": 10 } }, @@ -9321,29 +7381,29 @@ }, "init": { "type": "CallExpression", - "start": 3059, - "end": 3076, + "start": 2490, + "end": 2507, "loc": { "start": { - "line": 91, + "line": 74, "column": 13 }, "end": { - "line": 91, + "line": 74, "column": 30 } }, "callee": { "type": "Identifier", - "start": 3059, - "end": 3061, + "start": 2490, + "end": 2492, "loc": { "start": { - "line": 91, + "line": 74, "column": 13 }, "end": { - "line": 91, + "line": 74, "column": 15 } }, @@ -9352,60 +7412,60 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3061, - "end": 3074, + "start": 2492, + "end": 2505, "loc": { "start": { - "line": 91, + "line": 74, "column": 15 }, "end": { - "line": 91, + "line": 74, "column": 28 } }, "params": [ { "type": "TSTypeLiteral", - "start": 3062, - "end": 3073, + "start": 2493, + "end": 2504, "loc": { "start": { - "line": 91, + "line": 74, "column": 16 }, "end": { - "line": 91, + "line": 74, "column": 27 } }, "members": [ { "type": "TSPropertySignature", - "start": 3064, - "end": 3071, + "start": 2495, + "end": 2502, "loc": { "start": { - "line": 91, + "line": 74, "column": 18 }, "end": { - "line": 91, + "line": 74, "column": 25 } }, "computed": false, "key": { "type": "Identifier", - "start": 3064, - "end": 3065, + "start": 2495, + "end": 2496, "loc": { "start": { - "line": 91, + "line": 74, "column": 18 }, "end": { - "line": 91, + "line": 74, "column": 19 } }, @@ -9413,43 +7473,43 @@ }, "typeAnnotation": { "type": "TSTypeAnnotation", - "start": 3065, - "end": 3071, + "start": 2496, + "end": 2502, "loc": { "start": { - "line": 91, + "line": 74, "column": 19 }, "end": { - "line": 91, + "line": 74, "column": 25 } }, "typeAnnotation": { "type": "TSTypeReference", - "start": 3067, - "end": 3071, + "start": 2498, + "end": 2502, "loc": { "start": { - "line": 91, + "line": 74, "column": 21 }, "end": { - "line": 91, + "line": 74, "column": 25 } }, "typeName": { "type": "Identifier", - "start": 3067, - "end": 3068, + "start": 2498, + "end": 2499, "loc": { "start": { - "line": 91, + "line": 74, "column": 21 }, "end": { - "line": 91, + "line": 74, "column": 22 } }, @@ -9457,44 +7517,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3068, - "end": 3071, + "start": 2499, + "end": 2502, "loc": { "start": { - "line": 91, + "line": 74, "column": 22 }, "end": { - "line": 91, + "line": 74, "column": 25 } }, "params": [ { "type": "TSTypeReference", - "start": 3069, - "end": 3070, + "start": 2500, + "end": 2501, "loc": { "start": { - "line": 91, + "line": 74, "column": 23 }, "end": { - "line": 91, + "line": 74, "column": 24 } }, "typeName": { "type": "Identifier", - "start": 3069, - "end": 3070, + "start": 2500, + "end": 2501, "loc": { "start": { - "line": 91, + "line": 74, "column": 23 }, "end": { - "line": 91, + "line": 74, "column": 24 } }, @@ -9517,44 +7577,44 @@ }, { "type": "VariableDeclaration", - "start": 3079, - "end": 3107, + "start": 2510, + "end": 2538, "loc": { "start": { - "line": 92, + "line": 75, "column": 1 }, "end": { - "line": 92, + "line": 75, "column": 29 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3085, - "end": 3106, + "start": 2516, + "end": 2537, "loc": { "start": { - "line": 92, + "line": 75, "column": 7 }, "end": { - "line": 92, + "line": 75, "column": 28 } }, "id": { "type": "Identifier", - "start": 3085, - "end": 3088, + "start": 2516, + "end": 2519, "loc": { "start": { - "line": 92, + "line": 75, "column": 7 }, "end": { - "line": 92, + "line": 75, "column": 10 } }, @@ -9562,29 +7622,29 @@ }, "init": { "type": "CallExpression", - "start": 3091, - "end": 3106, + "start": 2522, + "end": 2537, "loc": { "start": { - "line": 92, + "line": 75, "column": 13 }, "end": { - "line": 92, + "line": 75, "column": 28 } }, "callee": { "type": "Identifier", - "start": 3091, - "end": 3093, + "start": 2522, + "end": 2524, "loc": { "start": { - "line": 92, + "line": 75, "column": 13 }, "end": { - "line": 92, + "line": 75, "column": 15 } }, @@ -9593,59 +7653,59 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3093, - "end": 3104, + "start": 2524, + "end": 2535, "loc": { "start": { - "line": 92, + "line": 75, "column": 15 }, "end": { - "line": 92, + "line": 75, "column": 26 } }, "params": [ { "type": "TSTupleType", - "start": 3094, - "end": 3103, + "start": 2525, + "end": 2534, "loc": { "start": { - "line": 92, + "line": 75, "column": 16 }, "end": { - "line": 92, + "line": 75, "column": 25 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 3095, - "end": 3102, + "start": 2526, + "end": 2533, "loc": { "start": { - "line": 92, + "line": 75, "column": 17 }, "end": { - "line": 92, + "line": 75, "column": 24 } }, "typeName": { "type": "Identifier", - "start": 3095, - "end": 3096, + "start": 2526, + "end": 2527, "loc": { "start": { - "line": 92, + "line": 75, "column": 17 }, "end": { - "line": 92, + "line": 75, "column": 18 } }, @@ -9653,44 +7713,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3096, - "end": 3102, + "start": 2527, + "end": 2533, "loc": { "start": { - "line": 92, + "line": 75, "column": 18 }, "end": { - "line": 92, + "line": 75, "column": 24 } }, "params": [ { "type": "TSTypeReference", - "start": 3097, - "end": 3098, + "start": 2528, + "end": 2529, "loc": { "start": { - "line": 92, + "line": 75, "column": 19 }, "end": { - "line": 92, + "line": 75, "column": 20 } }, "typeName": { "type": "Identifier", - "start": 3097, - "end": 3098, + "start": 2528, + "end": 2529, "loc": { "start": { - "line": 92, + "line": 75, "column": 19 }, "end": { - "line": 92, + "line": 75, "column": 20 } }, @@ -9699,29 +7759,29 @@ }, { "type": "TSTypeReference", - "start": 3100, - "end": 3101, + "start": 2531, + "end": 2532, "loc": { "start": { - "line": 92, + "line": 75, "column": 22 }, "end": { - "line": 92, + "line": 75, "column": 23 } }, "typeName": { "type": "Identifier", - "start": 3100, - "end": 3101, + "start": 2531, + "end": 2532, "loc": { "start": { - "line": 92, + "line": 75, "column": 22 }, "end": { - "line": 92, + "line": 75, "column": 23 } }, @@ -9742,44 +7802,44 @@ }, { "type": "VariableDeclaration", - "start": 3109, - "end": 3136, + "start": 2540, + "end": 2567, "loc": { "start": { - "line": 93, + "line": 76, "column": 1 }, "end": { - "line": 93, + "line": 76, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3115, - "end": 3135, + "start": 2546, + "end": 2566, "loc": { "start": { - "line": 93, + "line": 76, "column": 7 }, "end": { - "line": 93, + "line": 76, "column": 27 } }, "id": { "type": "Identifier", - "start": 3115, - "end": 3118, + "start": 2546, + "end": 2549, "loc": { "start": { - "line": 93, + "line": 76, "column": 7 }, "end": { - "line": 93, + "line": 76, "column": 10 } }, @@ -9787,29 +7847,29 @@ }, "init": { "type": "CallExpression", - "start": 3121, - "end": 3135, + "start": 2552, + "end": 2566, "loc": { "start": { - "line": 93, + "line": 76, "column": 13 }, "end": { - "line": 93, + "line": 76, "column": 27 } }, "callee": { "type": "Identifier", - "start": 3121, - "end": 3123, + "start": 2552, + "end": 2554, "loc": { "start": { - "line": 93, + "line": 76, "column": 13 }, "end": { - "line": 93, + "line": 76, "column": 15 } }, @@ -9818,73 +7878,73 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3123, - "end": 3133, + "start": 2554, + "end": 2564, "loc": { "start": { - "line": 93, + "line": 76, "column": 15 }, "end": { - "line": 93, + "line": 76, "column": 25 } }, "params": [ { "type": "TSTupleType", - "start": 3124, - "end": 3132, + "start": 2555, + "end": 2563, "loc": { "start": { - "line": 93, + "line": 76, "column": 16 }, "end": { - "line": 93, + "line": 76, "column": 24 } }, "elementTypes": [ { "type": "TSArrayType", - "start": 3125, - "end": 3131, + "start": 2556, + "end": 2562, "loc": { "start": { - "line": 93, + "line": 76, "column": 17 }, "end": { - "line": 93, + "line": 76, "column": 23 } }, "elementType": { "type": "TSTypeReference", - "start": 3125, - "end": 3129, + "start": 2556, + "end": 2560, "loc": { "start": { - "line": 93, + "line": 76, "column": 17 }, "end": { - "line": 93, + "line": 76, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 3125, - "end": 3126, + "start": 2556, + "end": 2557, "loc": { "start": { - "line": 93, + "line": 76, "column": 17 }, "end": { - "line": 93, + "line": 76, "column": 18 } }, @@ -9892,44 +7952,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3126, - "end": 3129, + "start": 2557, + "end": 2560, "loc": { "start": { - "line": 93, + "line": 76, "column": 18 }, "end": { - "line": 93, + "line": 76, "column": 21 } }, "params": [ { "type": "TSTypeReference", - "start": 3127, - "end": 3128, + "start": 2558, + "end": 2559, "loc": { "start": { - "line": 93, + "line": 76, "column": 19 }, "end": { - "line": 93, + "line": 76, "column": 20 } }, "typeName": { "type": "Identifier", - "start": 3127, - "end": 3128, + "start": 2558, + "end": 2559, "loc": { "start": { - "line": 93, + "line": 76, "column": 19 }, "end": { - "line": 93, + "line": 76, "column": 20 } }, @@ -9951,44 +8011,44 @@ }, { "type": "VariableDeclaration", - "start": 3138, - "end": 3166, + "start": 2569, + "end": 2597, "loc": { "start": { - "line": 94, + "line": 77, "column": 1 }, "end": { - "line": 94, + "line": 77, "column": 29 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3144, - "end": 3165, + "start": 2575, + "end": 2596, "loc": { "start": { - "line": 94, + "line": 77, "column": 7 }, "end": { - "line": 94, + "line": 77, "column": 28 } }, "id": { "type": "Identifier", - "start": 3144, - "end": 3147, + "start": 2575, + "end": 2578, "loc": { "start": { - "line": 94, + "line": 77, "column": 7 }, "end": { - "line": 94, + "line": 77, "column": 10 } }, @@ -9996,29 +8056,29 @@ }, "init": { "type": "CallExpression", - "start": 3150, - "end": 3165, + "start": 2581, + "end": 2596, "loc": { "start": { - "line": 94, + "line": 77, "column": 13 }, "end": { - "line": 94, + "line": 77, "column": 28 } }, "callee": { "type": "Identifier", - "start": 3150, - "end": 3152, + "start": 2581, + "end": 2583, "loc": { "start": { - "line": 94, + "line": 77, "column": 13 }, "end": { - "line": 94, + "line": 77, "column": 15 } }, @@ -10027,59 +8087,59 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3152, - "end": 3163, + "start": 2583, + "end": 2594, "loc": { "start": { - "line": 94, + "line": 77, "column": 15 }, "end": { - "line": 94, + "line": 77, "column": 26 } }, "params": [ { "type": "TSTupleType", - "start": 3153, - "end": 3159, + "start": 2584, + "end": 2590, "loc": { "start": { - "line": 94, + "line": 77, "column": 16 }, "end": { - "line": 94, + "line": 77, "column": 22 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 3154, - "end": 3158, + "start": 2585, + "end": 2589, "loc": { "start": { - "line": 94, + "line": 77, "column": 17 }, "end": { - "line": 94, + "line": 77, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 3154, - "end": 3155, + "start": 2585, + "end": 2586, "loc": { "start": { - "line": 94, + "line": 77, "column": 17 }, "end": { - "line": 94, + "line": 77, "column": 18 } }, @@ -10087,44 +8147,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3155, - "end": 3158, + "start": 2586, + "end": 2589, "loc": { "start": { - "line": 94, + "line": 77, "column": 18 }, "end": { - "line": 94, + "line": 77, "column": 21 } }, "params": [ { "type": "TSTypeReference", - "start": 3156, - "end": 3157, + "start": 2587, + "end": 2588, "loc": { "start": { - "line": 94, + "line": 77, "column": 19 }, "end": { - "line": 94, + "line": 77, "column": 20 } }, "typeName": { "type": "Identifier", - "start": 3156, - "end": 3157, + "start": 2587, + "end": 2588, "loc": { "start": { - "line": 94, + "line": 77, "column": 19 }, "end": { - "line": 94, + "line": 77, "column": 20 } }, @@ -10138,29 +8198,29 @@ }, { "type": "TSTypeReference", - "start": 3161, - "end": 3162, + "start": 2592, + "end": 2593, "loc": { "start": { - "line": 94, + "line": 77, "column": 24 }, "end": { - "line": 94, + "line": 77, "column": 25 } }, "typeName": { "type": "Identifier", - "start": 3161, - "end": 3162, + "start": 2592, + "end": 2593, "loc": { "start": { - "line": 94, + "line": 77, "column": 24 }, "end": { - "line": 94, + "line": 77, "column": 25 } }, @@ -10176,44 +8236,44 @@ }, { "type": "VariableDeclaration", - "start": 3168, - "end": 3195, + "start": 2599, + "end": 2626, "loc": { "start": { - "line": 95, + "line": 78, "column": 1 }, "end": { - "line": 95, + "line": 78, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3174, - "end": 3194, + "start": 2605, + "end": 2625, "loc": { "start": { - "line": 95, + "line": 78, "column": 7 }, "end": { - "line": 95, + "line": 78, "column": 27 } }, "id": { "type": "Identifier", - "start": 3174, - "end": 3177, + "start": 2605, + "end": 2608, "loc": { "start": { - "line": 95, + "line": 78, "column": 7 }, "end": { - "line": 95, + "line": 78, "column": 10 } }, @@ -10221,29 +8281,29 @@ }, "init": { "type": "CallExpression", - "start": 3180, - "end": 3194, + "start": 2611, + "end": 2625, "loc": { "start": { - "line": 95, + "line": 78, "column": 13 }, "end": { - "line": 95, + "line": 78, "column": 27 } }, "callee": { "type": "Identifier", - "start": 3180, - "end": 3182, + "start": 2611, + "end": 2613, "loc": { "start": { - "line": 95, + "line": 78, "column": 13 }, "end": { - "line": 95, + "line": 78, "column": 15 } }, @@ -10252,74 +8312,74 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3182, - "end": 3192, + "start": 2613, + "end": 2623, "loc": { "start": { - "line": 95, + "line": 78, "column": 15 }, "end": { - "line": 95, + "line": 78, "column": 25 } }, "params": [ { "type": "TSTupleType", - "start": 3183, - "end": 3191, + "start": 2614, + "end": 2622, "loc": { "start": { - "line": 95, + "line": 78, "column": 16 }, "end": { - "line": 95, + "line": 78, "column": 24 } }, "elementTypes": [ { "type": "TSTupleType", - "start": 3184, - "end": 3190, + "start": 2615, + "end": 2621, "loc": { "start": { - "line": 95, + "line": 78, "column": 17 }, "end": { - "line": 95, + "line": 78, "column": 23 } }, "elementTypes": [ { "type": "TSTypeReference", - "start": 3185, - "end": 3189, + "start": 2616, + "end": 2620, "loc": { "start": { - "line": 95, + "line": 78, "column": 18 }, "end": { - "line": 95, + "line": 78, "column": 22 } }, "typeName": { "type": "Identifier", - "start": 3185, - "end": 3186, + "start": 2616, + "end": 2617, "loc": { "start": { - "line": 95, + "line": 78, "column": 18 }, "end": { - "line": 95, + "line": 78, "column": 19 } }, @@ -10327,44 +8387,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3186, - "end": 3189, + "start": 2617, + "end": 2620, "loc": { "start": { - "line": 95, + "line": 78, "column": 19 }, "end": { - "line": 95, + "line": 78, "column": 22 } }, "params": [ { "type": "TSTypeReference", - "start": 3187, - "end": 3188, + "start": 2618, + "end": 2619, "loc": { "start": { - "line": 95, + "line": 78, "column": 20 }, "end": { - "line": 95, + "line": 78, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 3187, - "end": 3188, + "start": 2618, + "end": 2619, "loc": { "start": { - "line": 95, + "line": 78, "column": 20 }, "end": { - "line": 95, + "line": 78, "column": 21 } }, @@ -10387,44 +8447,44 @@ }, { "type": "VariableDeclaration", - "start": 3307, - "end": 3328, + "start": 2738, + "end": 2759, "loc": { "start": { - "line": 99, + "line": 82, "column": 1 }, "end": { - "line": 99, + "line": 82, "column": 22 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3313, - "end": 3327, + "start": 2744, + "end": 2758, "loc": { "start": { - "line": 99, + "line": 82, "column": 7 }, "end": { - "line": 99, + "line": 82, "column": 21 } }, "id": { "type": "Identifier", - "start": 3313, - "end": 3316, + "start": 2744, + "end": 2747, "loc": { "start": { - "line": 99, + "line": 82, "column": 7 }, "end": { - "line": 99, + "line": 82, "column": 10 } }, @@ -10432,29 +8492,29 @@ }, "init": { "type": "TaggedTemplateExpression", - "start": 3319, - "end": 3327, + "start": 2750, + "end": 2758, "loc": { "start": { - "line": 99, + "line": 82, "column": 13 }, "end": { - "line": 99, + "line": 82, "column": 21 } }, "tag": { "type": "Identifier", - "start": 3319, - "end": 3321, + "start": 2750, + "end": 2752, "loc": { "start": { - "line": 99, + "line": 82, "column": 13 }, "end": { - "line": 99, + "line": 82, "column": 15 } }, @@ -10462,15 +8522,15 @@ }, "quasi": { "type": "TemplateLiteral", - "start": 3324, - "end": 3327, + "start": 2755, + "end": 2758, "loc": { "start": { - "line": 99, + "line": 82, "column": 18 }, "end": { - "line": 99, + "line": 82, "column": 21 } }, @@ -10478,15 +8538,15 @@ "quasis": [ { "type": "TemplateElement", - "start": 3325, - "end": 3326, + "start": 2756, + "end": 2757, "loc": { "start": { - "line": 99, + "line": 82, "column": 19 }, "end": { - "line": 99, + "line": 82, "column": 20 } }, @@ -10500,44 +8560,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3321, - "end": 3324, + "start": 2752, + "end": 2755, "loc": { "start": { - "line": 99, + "line": 82, "column": 15 }, "end": { - "line": 99, + "line": 82, "column": 18 } }, "params": [ { "type": "TSTypeReference", - "start": 3322, - "end": 3323, + "start": 2753, + "end": 2754, "loc": { "start": { - "line": 99, + "line": 82, "column": 16 }, "end": { - "line": 99, + "line": 82, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3322, - "end": 3323, + "start": 2753, + "end": 2754, "loc": { "start": { - "line": 99, + "line": 82, "column": 16 }, "end": { - "line": 99, + "line": 82, "column": 17 } }, @@ -10554,57 +8614,57 @@ { "type": "Line", "value": " a template literal after the closing `>` is a tagged template on the", - "start": 3198, - "end": 3269 + "start": 2629, + "end": 2700 }, { "type": "Line", "value": " instantiation, not a comparison", - "start": 3271, - "end": 3305 + "start": 2702, + "end": 2736 } ] }, { "type": "VariableDeclaration", - "start": 3465, - "end": 3487, + "start": 2896, + "end": 2918, "loc": { "start": { - "line": 103, + "line": 86, "column": 1 }, "end": { - "line": 103, + "line": 86, "column": 23 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3471, - "end": 3486, + "start": 2902, + "end": 2917, "loc": { "start": { - "line": 103, + "line": 86, "column": 7 }, "end": { - "line": 103, + "line": 86, "column": 22 } }, "id": { "type": "Identifier", - "start": 3471, - "end": 3474, + "start": 2902, + "end": 2905, "loc": { "start": { - "line": 103, + "line": 86, "column": 7 }, "end": { - "line": 103, + "line": 86, "column": 10 } }, @@ -10612,29 +8672,29 @@ }, "init": { "type": "CallExpression", - "start": 3477, - "end": 3486, + "start": 2908, + "end": 2917, "loc": { "start": { - "line": 103, + "line": 86, "column": 13 }, "end": { - "line": 103, + "line": 86, "column": 22 } }, "callee": { "type": "Identifier", - "start": 3477, - "end": 3479, + "start": 2908, + "end": 2910, "loc": { "start": { - "line": 103, + "line": 86, "column": 13 }, "end": { - "line": 103, + "line": 86, "column": 15 } }, @@ -10643,58 +8703,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3479, - "end": 3484, + "start": 2910, + "end": 2915, "loc": { "start": { - "line": 103, + "line": 86, "column": 15 }, "end": { - "line": 103, + "line": 86, "column": 20 } }, "params": [ { "type": "TSArrayType", - "start": 3480, - "end": 3483, + "start": 2911, + "end": 2914, "loc": { "start": { - "line": 103, + "line": 86, "column": 16 }, "end": { - "line": 103, + "line": 86, "column": 19 } }, "elementType": { "type": "TSTypeReference", - "start": 3480, - "end": 3481, + "start": 2911, + "end": 2912, "loc": { "start": { - "line": 103, + "line": 86, "column": 16 }, "end": { - "line": 103, + "line": 86, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3480, - "end": 3481, + "start": 2911, + "end": 2912, "loc": { "start": { - "line": 103, + "line": 86, "column": 16 }, "end": { - "line": 103, + "line": 86, "column": 17 } }, @@ -10712,57 +8772,57 @@ { "type": "Line", "value": " an indexed access, array, or conditional type argument still parses as type", - "start": 3331, - "end": 3409 + "start": 2762, + "end": 2840 }, { "type": "Line", "value": " arguments — the closing `>` is followed by a call", - "start": 3411, - "end": 3463 + "start": 2842, + "end": 2894 } ] }, { "type": "VariableDeclaration", - "start": 3489, - "end": 3514, + "start": 2920, + "end": 2945, "loc": { "start": { - "line": 104, + "line": 87, "column": 1 }, "end": { - "line": 104, + "line": 87, "column": 26 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3495, - "end": 3513, + "start": 2926, + "end": 2944, "loc": { "start": { - "line": 104, + "line": 87, "column": 7 }, "end": { - "line": 104, + "line": 87, "column": 25 } }, "id": { "type": "Identifier", - "start": 3495, - "end": 3498, + "start": 2926, + "end": 2929, "loc": { "start": { - "line": 104, + "line": 87, "column": 7 }, "end": { - "line": 104, + "line": 87, "column": 10 } }, @@ -10770,29 +8830,29 @@ }, "init": { "type": "CallExpression", - "start": 3501, - "end": 3513, + "start": 2932, + "end": 2944, "loc": { "start": { - "line": 104, + "line": 87, "column": 13 }, "end": { - "line": 104, + "line": 87, "column": 25 } }, "callee": { "type": "Identifier", - "start": 3501, - "end": 3503, + "start": 2932, + "end": 2934, "loc": { "start": { - "line": 104, + "line": 87, "column": 13 }, "end": { - "line": 104, + "line": 87, "column": 15 } }, @@ -10801,58 +8861,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3503, - "end": 3511, + "start": 2934, + "end": 2942, "loc": { "start": { - "line": 104, + "line": 87, "column": 15 }, "end": { - "line": 104, + "line": 87, "column": 23 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3504, - "end": 3510, + "start": 2935, + "end": 2941, "loc": { "start": { - "line": 104, + "line": 87, "column": 16 }, "end": { - "line": 104, + "line": 87, "column": 22 } }, "objectType": { "type": "TSTypeReference", - "start": 3504, - "end": 3505, + "start": 2935, + "end": 2936, "loc": { "start": { - "line": 104, + "line": 87, "column": 16 }, "end": { - "line": 104, + "line": 87, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3504, - "end": 3505, + "start": 2935, + "end": 2936, "loc": { "start": { - "line": 104, + "line": 87, "column": 16 }, "end": { - "line": 104, + "line": 87, "column": 17 } }, @@ -10861,29 +8921,29 @@ }, "indexType": { "type": "TSLiteralType", - "start": 3506, - "end": 3509, + "start": 2937, + "end": 2940, "loc": { "start": { - "line": 104, + "line": 87, "column": 18 }, "end": { - "line": 104, + "line": 87, "column": 21 } }, "literal": { "type": "Literal", - "start": 3506, - "end": 3509, + "start": 2937, + "end": 2940, "loc": { "start": { - "line": 104, + "line": 87, "column": 18 }, "end": { - "line": 104, + "line": 87, "column": 21 } }, @@ -10901,44 +8961,44 @@ }, { "type": "VariableDeclaration", - "start": 3516, - "end": 3542, + "start": 2947, + "end": 2973, "loc": { "start": { - "line": 105, + "line": 88, "column": 1 }, "end": { - "line": 105, + "line": 88, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3522, - "end": 3541, + "start": 2953, + "end": 2972, "loc": { "start": { - "line": 105, + "line": 88, "column": 7 }, "end": { - "line": 105, + "line": 88, "column": 26 } }, "id": { "type": "Identifier", - "start": 3522, - "end": 3525, + "start": 2953, + "end": 2956, "loc": { "start": { - "line": 105, + "line": 88, "column": 7 }, "end": { - "line": 105, + "line": 88, "column": 10 } }, @@ -10946,29 +9006,29 @@ }, "init": { "type": "CallExpression", - "start": 3528, - "end": 3541, + "start": 2959, + "end": 2972, "loc": { "start": { - "line": 105, + "line": 88, "column": 13 }, "end": { - "line": 105, + "line": 88, "column": 26 } }, "callee": { "type": "Identifier", - "start": 3528, - "end": 3530, + "start": 2959, + "end": 2961, "loc": { "start": { - "line": 105, + "line": 88, "column": 13 }, "end": { - "line": 105, + "line": 88, "column": 15 } }, @@ -10977,58 +9037,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3530, - "end": 3539, + "start": 2961, + "end": 2970, "loc": { "start": { - "line": 105, + "line": 88, "column": 15 }, "end": { - "line": 105, + "line": 88, "column": 24 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3531, - "end": 3535, + "start": 2962, + "end": 2966, "loc": { "start": { - "line": 105, + "line": 88, "column": 16 }, "end": { - "line": 105, + "line": 88, "column": 20 } }, "objectType": { "type": "TSTypeReference", - "start": 3531, - "end": 3532, + "start": 2962, + "end": 2963, "loc": { "start": { - "line": 105, + "line": 88, "column": 16 }, "end": { - "line": 105, + "line": 88, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3531, - "end": 3532, + "start": 2962, + "end": 2963, "loc": { "start": { - "line": 105, + "line": 88, "column": 16 }, "end": { - "line": 105, + "line": 88, "column": 17 } }, @@ -11037,29 +9097,29 @@ }, "indexType": { "type": "TSTypeReference", - "start": 3533, - "end": 3534, + "start": 2964, + "end": 2965, "loc": { "start": { - "line": 105, + "line": 88, "column": 18 }, "end": { - "line": 105, + "line": 88, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3533, - "end": 3534, + "start": 2964, + "end": 2965, "loc": { "start": { - "line": 105, + "line": 88, "column": 18 }, "end": { - "line": 105, + "line": 88, "column": 19 } }, @@ -11069,29 +9129,29 @@ }, { "type": "TSTypeReference", - "start": 3537, - "end": 3538, + "start": 2968, + "end": 2969, "loc": { "start": { - "line": 105, + "line": 88, "column": 22 }, "end": { - "line": 105, + "line": 88, "column": 23 } }, "typeName": { "type": "Identifier", - "start": 3537, - "end": 3538, + "start": 2968, + "end": 2969, "loc": { "start": { - "line": 105, + "line": 88, "column": 22 }, "end": { - "line": 105, + "line": 88, "column": 23 } }, @@ -11107,44 +9167,44 @@ }, { "type": "VariableDeclaration", - "start": 3544, - "end": 3573, + "start": 2975, + "end": 3004, "loc": { "start": { - "line": 106, + "line": 89, "column": 1 }, "end": { - "line": 106, + "line": 89, "column": 30 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3550, - "end": 3572, + "start": 2981, + "end": 3003, "loc": { "start": { - "line": 106, + "line": 89, "column": 7 }, "end": { - "line": 106, + "line": 89, "column": 29 } }, "id": { "type": "Identifier", - "start": 3550, - "end": 3553, + "start": 2981, + "end": 2984, "loc": { "start": { - "line": 106, + "line": 89, "column": 7 }, "end": { - "line": 106, + "line": 89, "column": 10 } }, @@ -11152,29 +9212,29 @@ }, "init": { "type": "CallExpression", - "start": 3556, - "end": 3572, + "start": 2987, + "end": 3003, "loc": { "start": { - "line": 106, + "line": 89, "column": 13 }, "end": { - "line": 106, + "line": 89, "column": 29 } }, "callee": { "type": "Identifier", - "start": 3556, - "end": 3558, + "start": 2987, + "end": 2989, "loc": { "start": { - "line": 106, + "line": 89, "column": 13 }, "end": { - "line": 106, + "line": 89, "column": 15 } }, @@ -11183,58 +9243,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3558, - "end": 3570, + "start": 2989, + "end": 3001, "loc": { "start": { - "line": 106, + "line": 89, "column": 15 }, "end": { - "line": 106, + "line": 89, "column": 27 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3559, - "end": 3569, + "start": 2990, + "end": 3000, "loc": { "start": { - "line": 106, + "line": 89, "column": 16 }, "end": { - "line": 106, + "line": 89, "column": 26 } }, "objectType": { "type": "TSTypeReference", - "start": 3559, - "end": 3560, + "start": 2990, + "end": 2991, "loc": { "start": { - "line": 106, + "line": 89, "column": 16 }, "end": { - "line": 106, + "line": 89, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3559, - "end": 3560, + "start": 2990, + "end": 2991, "loc": { "start": { - "line": 106, + "line": 89, "column": 16 }, "end": { - "line": 106, + "line": 89, "column": 17 } }, @@ -11243,44 +9303,44 @@ }, "indexType": { "type": "TSTypeOperator", - "start": 3561, - "end": 3568, + "start": 2992, + "end": 2999, "loc": { "start": { - "line": 106, + "line": 89, "column": 18 }, "end": { - "line": 106, + "line": 89, "column": 25 } }, "operator": "keyof", "typeAnnotation": { "type": "TSTypeReference", - "start": 3567, - "end": 3568, + "start": 2998, + "end": 2999, "loc": { "start": { - "line": 106, + "line": 89, "column": 24 }, "end": { - "line": 106, + "line": 89, "column": 25 } }, "typeName": { "type": "Identifier", - "start": 3567, - "end": 3568, + "start": 2998, + "end": 2999, "loc": { "start": { - "line": 106, + "line": 89, "column": 24 }, "end": { - "line": 106, + "line": 89, "column": 25 } }, @@ -11298,44 +9358,44 @@ }, { "type": "VariableDeclaration", - "start": 3575, - "end": 3605, + "start": 3006, + "end": 3036, "loc": { "start": { - "line": 107, + "line": 90, "column": 1 }, "end": { - "line": 107, + "line": 90, "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3581, - "end": 3604, + "start": 3012, + "end": 3035, "loc": { "start": { - "line": 107, + "line": 90, "column": 7 }, "end": { - "line": 107, + "line": 90, "column": 30 } }, "id": { "type": "Identifier", - "start": 3581, - "end": 3584, + "start": 3012, + "end": 3015, "loc": { "start": { - "line": 107, + "line": 90, "column": 7 }, "end": { - "line": 107, + "line": 90, "column": 10 } }, @@ -11343,29 +9403,29 @@ }, "init": { "type": "CallExpression", - "start": 3587, - "end": 3604, + "start": 3018, + "end": 3035, "loc": { "start": { - "line": 107, + "line": 90, "column": 13 }, "end": { - "line": 107, + "line": 90, "column": 30 } }, "callee": { "type": "Identifier", - "start": 3587, - "end": 3589, + "start": 3018, + "end": 3020, "loc": { "start": { - "line": 107, + "line": 90, "column": 13 }, "end": { - "line": 107, + "line": 90, "column": 15 } }, @@ -11374,58 +9434,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3589, - "end": 3602, + "start": 3020, + "end": 3033, "loc": { "start": { - "line": 107, + "line": 90, "column": 15 }, "end": { - "line": 107, + "line": 90, "column": 28 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3590, - "end": 3601, + "start": 3021, + "end": 3032, "loc": { "start": { - "line": 107, + "line": 90, "column": 16 }, "end": { - "line": 107, + "line": 90, "column": 27 } }, "objectType": { "type": "TSTypeReference", - "start": 3590, - "end": 3591, + "start": 3021, + "end": 3022, "loc": { "start": { - "line": 107, + "line": 90, "column": 16 }, "end": { - "line": 107, + "line": 90, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3590, - "end": 3591, + "start": 3021, + "end": 3022, "loc": { "start": { - "line": 107, + "line": 90, "column": 16 }, "end": { - "line": 107, + "line": 90, "column": 17 } }, @@ -11434,29 +9494,29 @@ }, "indexType": { "type": "TSTypeQuery", - "start": 3592, - "end": 3600, + "start": 3023, + "end": 3031, "loc": { "start": { - "line": 107, + "line": 90, "column": 18 }, "end": { - "line": 107, + "line": 90, "column": 26 } }, "exprName": { "type": "Identifier", - "start": 3599, - "end": 3600, + "start": 3030, + "end": 3031, "loc": { "start": { - "line": 107, + "line": 90, "column": 25 }, "end": { - "line": 107, + "line": 90, "column": 26 } }, @@ -11473,44 +9533,44 @@ }, { "type": "VariableDeclaration", - "start": 3607, - "end": 3633, + "start": 3038, + "end": 3064, "loc": { "start": { - "line": 108, + "line": 91, "column": 1 }, "end": { - "line": 108, + "line": 91, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3613, - "end": 3632, + "start": 3044, + "end": 3063, "loc": { "start": { - "line": 108, + "line": 91, "column": 7 }, "end": { - "line": 108, + "line": 91, "column": 26 } }, "id": { "type": "Identifier", - "start": 3613, - "end": 3616, + "start": 3044, + "end": 3047, "loc": { "start": { - "line": 108, + "line": 91, "column": 7 }, "end": { - "line": 108, + "line": 91, "column": 10 } }, @@ -11518,29 +9578,29 @@ }, "init": { "type": "CallExpression", - "start": 3619, - "end": 3632, + "start": 3050, + "end": 3063, "loc": { "start": { - "line": 108, + "line": 91, "column": 13 }, "end": { - "line": 108, + "line": 91, "column": 26 } }, "callee": { "type": "Identifier", - "start": 3619, - "end": 3621, + "start": 3050, + "end": 3052, "loc": { "start": { - "line": 108, + "line": 91, "column": 13 }, "end": { - "line": 108, + "line": 91, "column": 15 } }, @@ -11549,72 +9609,72 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3621, - "end": 3630, + "start": 3052, + "end": 3061, "loc": { "start": { - "line": 108, + "line": 91, "column": 15 }, "end": { - "line": 108, + "line": 91, "column": 24 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3622, - "end": 3629, + "start": 3053, + "end": 3060, "loc": { "start": { - "line": 108, + "line": 91, "column": 16 }, "end": { - "line": 108, + "line": 91, "column": 23 } }, "objectType": { "type": "TSIndexedAccessType", - "start": 3622, - "end": 3626, + "start": 3053, + "end": 3057, "loc": { "start": { - "line": 108, + "line": 91, "column": 16 }, "end": { - "line": 108, + "line": 91, "column": 20 } }, "objectType": { "type": "TSTypeReference", - "start": 3622, - "end": 3623, + "start": 3053, + "end": 3054, "loc": { "start": { - "line": 108, + "line": 91, "column": 16 }, "end": { - "line": 108, + "line": 91, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3622, - "end": 3623, + "start": 3053, + "end": 3054, "loc": { "start": { - "line": 108, + "line": 91, "column": 16 }, "end": { - "line": 108, + "line": 91, "column": 17 } }, @@ -11623,29 +9683,29 @@ }, "indexType": { "type": "TSTypeReference", - "start": 3624, - "end": 3625, + "start": 3055, + "end": 3056, "loc": { "start": { - "line": 108, + "line": 91, "column": 18 }, "end": { - "line": 108, + "line": 91, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3624, - "end": 3625, + "start": 3055, + "end": 3056, "loc": { "start": { - "line": 108, + "line": 91, "column": 18 }, "end": { - "line": 108, + "line": 91, "column": 19 } }, @@ -11655,29 +9715,29 @@ }, "indexType": { "type": "TSTypeReference", - "start": 3627, - "end": 3628, + "start": 3058, + "end": 3059, "loc": { "start": { - "line": 108, + "line": 91, "column": 21 }, "end": { - "line": 108, + "line": 91, "column": 22 } }, "typeName": { "type": "Identifier", - "start": 3627, - "end": 3628, + "start": 3058, + "end": 3059, "loc": { "start": { - "line": 108, + "line": 91, "column": 21 }, "end": { - "line": 108, + "line": 91, "column": 22 } }, @@ -11694,44 +9754,44 @@ }, { "type": "VariableDeclaration", - "start": 3635, - "end": 3673, + "start": 3066, + "end": 3104, "loc": { "start": { - "line": 109, + "line": 92, "column": 1 }, "end": { - "line": 109, + "line": 92, "column": 39 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3641, - "end": 3672, + "start": 3072, + "end": 3103, "loc": { "start": { - "line": 109, + "line": 92, "column": 7 }, "end": { - "line": 109, + "line": 92, "column": 38 } }, "id": { "type": "Identifier", - "start": 3641, - "end": 3644, + "start": 3072, + "end": 3075, "loc": { "start": { - "line": 109, + "line": 92, "column": 7 }, "end": { - "line": 109, + "line": 92, "column": 10 } }, @@ -11739,29 +9799,29 @@ }, "init": { "type": "CallExpression", - "start": 3647, - "end": 3672, + "start": 3078, + "end": 3103, "loc": { "start": { - "line": 109, + "line": 92, "column": 13 }, "end": { - "line": 109, + "line": 92, "column": 38 } }, "callee": { "type": "Identifier", - "start": 3647, - "end": 3649, + "start": 3078, + "end": 3080, "loc": { "start": { - "line": 109, + "line": 92, "column": 13 }, "end": { - "line": 109, + "line": 92, "column": 15 } }, @@ -11770,58 +9830,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3649, - "end": 3670, + "start": 3080, + "end": 3101, "loc": { "start": { - "line": 109, + "line": 92, "column": 15 }, "end": { - "line": 109, + "line": 92, "column": 36 } }, "params": [ { "type": "TSConditionalType", - "start": 3650, - "end": 3669, + "start": 3081, + "end": 3100, "loc": { "start": { - "line": 109, + "line": 92, "column": 16 }, "end": { - "line": 109, + "line": 92, "column": 35 } }, "checkType": { "type": "TSTypeReference", - "start": 3650, - "end": 3651, + "start": 3081, + "end": 3082, "loc": { "start": { - "line": 109, + "line": 92, "column": 16 }, "end": { - "line": 109, + "line": 92, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3650, - "end": 3651, + "start": 3081, + "end": 3082, "loc": { "start": { - "line": 109, + "line": 92, "column": 16 }, "end": { - "line": 109, + "line": 92, "column": 17 } }, @@ -11830,29 +9890,29 @@ }, "extendsType": { "type": "TSTypeReference", - "start": 3660, - "end": 3661, + "start": 3091, + "end": 3092, "loc": { "start": { - "line": 109, + "line": 92, "column": 26 }, "end": { - "line": 109, + "line": 92, "column": 27 } }, "typeName": { "type": "Identifier", - "start": 3660, - "end": 3661, + "start": 3091, + "end": 3092, "loc": { "start": { - "line": 109, + "line": 92, "column": 26 }, "end": { - "line": 109, + "line": 92, "column": 27 } }, @@ -11861,29 +9921,29 @@ }, "trueType": { "type": "TSTypeReference", - "start": 3664, - "end": 3665, + "start": 3095, + "end": 3096, "loc": { "start": { - "line": 109, + "line": 92, "column": 30 }, "end": { - "line": 109, + "line": 92, "column": 31 } }, "typeName": { "type": "Identifier", - "start": 3664, - "end": 3665, + "start": 3095, + "end": 3096, "loc": { "start": { - "line": 109, + "line": 92, "column": 30 }, "end": { - "line": 109, + "line": 92, "column": 31 } }, @@ -11892,29 +9952,29 @@ }, "falseType": { "type": "TSTypeReference", - "start": 3668, - "end": 3669, + "start": 3099, + "end": 3100, "loc": { "start": { - "line": 109, + "line": 92, "column": 34 }, "end": { - "line": 109, + "line": 92, "column": 35 } }, "typeName": { "type": "Identifier", - "start": 3668, - "end": 3669, + "start": 3099, + "end": 3100, "loc": { "start": { - "line": 109, + "line": 92, "column": 34 }, "end": { - "line": 109, + "line": 92, "column": 35 } }, @@ -11931,44 +9991,44 @@ }, { "type": "VariableDeclaration", - "start": 3834, - "end": 3861, + "start": 3265, + "end": 3292, "loc": { "start": { - "line": 113, + "line": 96, "column": 1 }, "end": { - "line": 113, + "line": 96, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3840, - "end": 3860, + "start": 3271, + "end": 3291, "loc": { "start": { - "line": 113, + "line": 96, "column": 7 }, "end": { - "line": 113, + "line": 96, "column": 27 } }, "id": { "type": "Identifier", - "start": 3840, - "end": 3843, + "start": 3271, + "end": 3274, "loc": { "start": { - "line": 113, + "line": 96, "column": 7 }, "end": { - "line": 113, + "line": 96, "column": 10 } }, @@ -11976,29 +10036,29 @@ }, "init": { "type": "CallExpression", - "start": 3846, - "end": 3860, + "start": 3277, + "end": 3291, "loc": { "start": { - "line": 113, + "line": 96, "column": 13 }, "end": { - "line": 113, + "line": 96, "column": 27 } }, "callee": { "type": "Identifier", - "start": 3846, - "end": 3848, + "start": 3277, + "end": 3279, "loc": { "start": { - "line": 113, + "line": 96, "column": 13 }, "end": { - "line": 113, + "line": 96, "column": 15 } }, @@ -12007,58 +10067,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3848, - "end": 3858, + "start": 3279, + "end": 3289, "loc": { "start": { - "line": 113, + "line": 96, "column": 15 }, "end": { - "line": 113, + "line": 96, "column": 25 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3849, - "end": 3857, + "start": 3280, + "end": 3288, "loc": { "start": { - "line": 113, + "line": 96, "column": 16 }, "end": { - "line": 113, + "line": 96, "column": 24 } }, "objectType": { "type": "TSTypeReference", - "start": 3849, - "end": 3850, + "start": 3280, + "end": 3281, "loc": { "start": { - "line": 113, + "line": 96, "column": 16 }, "end": { - "line": 113, + "line": 96, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3849, - "end": 3850, + "start": 3280, + "end": 3281, "loc": { "start": { - "line": 113, + "line": 96, "column": 16 }, "end": { - "line": 113, + "line": 96, "column": 17 } }, @@ -12067,44 +10127,44 @@ }, "indexType": { "type": "TSUnionType", - "start": 3851, - "end": 3856, + "start": 3282, + "end": 3287, "loc": { "start": { - "line": 113, + "line": 96, "column": 18 }, "end": { - "line": 113, + "line": 96, "column": 23 } }, "types": [ { "type": "TSTypeReference", - "start": 3851, - "end": 3852, + "start": 3282, + "end": 3283, "loc": { "start": { - "line": 113, + "line": 96, "column": 18 }, "end": { - "line": 113, + "line": 96, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3851, - "end": 3852, + "start": 3282, + "end": 3283, "loc": { "start": { - "line": 113, + "line": 96, "column": 18 }, "end": { - "line": 113, + "line": 96, "column": 19 } }, @@ -12113,29 +10173,29 @@ }, { "type": "TSTypeReference", - "start": 3855, - "end": 3856, + "start": 3286, + "end": 3287, "loc": { "start": { - "line": 113, + "line": 96, "column": 22 }, "end": { - "line": 113, + "line": 96, "column": 23 } }, "typeName": { "type": "Identifier", - "start": 3855, - "end": 3856, + "start": 3286, + "end": 3287, "loc": { "start": { - "line": 113, + "line": 96, "column": 22 }, "end": { - "line": 113, + "line": 96, "column": 23 } }, @@ -12155,57 +10215,57 @@ { "type": "Line", "value": " every index content that is itself a valid type — union, intersection, nested", - "start": 3676, - "end": 3756 + "start": 3107, + "end": 3187 }, { "type": "Line", "value": " index, numeric literal, and conditional — makes the list type arguments", - "start": 3758, - "end": 3832 + "start": 3189, + "end": 3263 } ] }, { "type": "VariableDeclaration", - "start": 3863, - "end": 3890, + "start": 3294, + "end": 3321, "loc": { "start": { - "line": 114, + "line": 97, "column": 1 }, "end": { - "line": 114, + "line": 97, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3869, - "end": 3889, + "start": 3300, + "end": 3320, "loc": { "start": { - "line": 114, + "line": 97, "column": 7 }, "end": { - "line": 114, + "line": 97, "column": 27 } }, "id": { "type": "Identifier", - "start": 3869, - "end": 3872, + "start": 3300, + "end": 3303, "loc": { "start": { - "line": 114, + "line": 97, "column": 7 }, "end": { - "line": 114, + "line": 97, "column": 10 } }, @@ -12213,29 +10273,29 @@ }, "init": { "type": "CallExpression", - "start": 3875, - "end": 3889, + "start": 3306, + "end": 3320, "loc": { "start": { - "line": 114, + "line": 97, "column": 13 }, "end": { - "line": 114, + "line": 97, "column": 27 } }, "callee": { "type": "Identifier", - "start": 3875, - "end": 3877, + "start": 3306, + "end": 3308, "loc": { "start": { - "line": 114, + "line": 97, "column": 13 }, "end": { - "line": 114, + "line": 97, "column": 15 } }, @@ -12244,58 +10304,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3877, - "end": 3887, + "start": 3308, + "end": 3318, "loc": { "start": { - "line": 114, + "line": 97, "column": 15 }, "end": { - "line": 114, + "line": 97, "column": 25 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3878, - "end": 3886, + "start": 3309, + "end": 3317, "loc": { "start": { - "line": 114, + "line": 97, "column": 16 }, "end": { - "line": 114, + "line": 97, "column": 24 } }, "objectType": { "type": "TSTypeReference", - "start": 3878, - "end": 3879, + "start": 3309, + "end": 3310, "loc": { "start": { - "line": 114, + "line": 97, "column": 16 }, "end": { - "line": 114, + "line": 97, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3878, - "end": 3879, + "start": 3309, + "end": 3310, "loc": { "start": { - "line": 114, + "line": 97, "column": 16 }, "end": { - "line": 114, + "line": 97, "column": 17 } }, @@ -12304,44 +10364,44 @@ }, "indexType": { "type": "TSIntersectionType", - "start": 3880, - "end": 3885, + "start": 3311, + "end": 3316, "loc": { "start": { - "line": 114, + "line": 97, "column": 18 }, "end": { - "line": 114, + "line": 97, "column": 23 } }, "types": [ { "type": "TSTypeReference", - "start": 3880, - "end": 3881, + "start": 3311, + "end": 3312, "loc": { "start": { - "line": 114, + "line": 97, "column": 18 }, "end": { - "line": 114, + "line": 97, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3880, - "end": 3881, + "start": 3311, + "end": 3312, "loc": { "start": { - "line": 114, + "line": 97, "column": 18 }, "end": { - "line": 114, + "line": 97, "column": 19 } }, @@ -12350,29 +10410,29 @@ }, { "type": "TSTypeReference", - "start": 3884, - "end": 3885, + "start": 3315, + "end": 3316, "loc": { "start": { - "line": 114, + "line": 97, "column": 22 }, "end": { - "line": 114, + "line": 97, "column": 23 } }, "typeName": { "type": "Identifier", - "start": 3884, - "end": 3885, + "start": 3315, + "end": 3316, "loc": { "start": { - "line": 114, + "line": 97, "column": 22 }, "end": { - "line": 114, + "line": 97, "column": 23 } }, @@ -12391,44 +10451,44 @@ }, { "type": "VariableDeclaration", - "start": 3892, - "end": 3918, + "start": 3323, + "end": 3349, "loc": { "start": { - "line": 115, + "line": 98, "column": 1 }, "end": { - "line": 115, + "line": 98, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3898, - "end": 3917, + "start": 3329, + "end": 3348, "loc": { "start": { - "line": 115, + "line": 98, "column": 7 }, "end": { - "line": 115, + "line": 98, "column": 26 } }, "id": { "type": "Identifier", - "start": 3898, - "end": 3901, + "start": 3329, + "end": 3332, "loc": { "start": { - "line": 115, + "line": 98, "column": 7 }, "end": { - "line": 115, + "line": 98, "column": 10 } }, @@ -12436,29 +10496,29 @@ }, "init": { "type": "CallExpression", - "start": 3904, - "end": 3917, + "start": 3335, + "end": 3348, "loc": { "start": { - "line": 115, + "line": 98, "column": 13 }, "end": { - "line": 115, + "line": 98, "column": 26 } }, "callee": { "type": "Identifier", - "start": 3904, - "end": 3906, + "start": 3335, + "end": 3337, "loc": { "start": { - "line": 115, + "line": 98, "column": 13 }, "end": { - "line": 115, + "line": 98, "column": 15 } }, @@ -12467,58 +10527,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3906, - "end": 3915, + "start": 3337, + "end": 3346, "loc": { "start": { - "line": 115, + "line": 98, "column": 15 }, "end": { - "line": 115, + "line": 98, "column": 24 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3907, - "end": 3914, + "start": 3338, + "end": 3345, "loc": { "start": { - "line": 115, + "line": 98, "column": 16 }, "end": { - "line": 115, + "line": 98, "column": 23 } }, "objectType": { "type": "TSTypeReference", - "start": 3907, - "end": 3908, + "start": 3338, + "end": 3339, "loc": { "start": { - "line": 115, + "line": 98, "column": 16 }, "end": { - "line": 115, + "line": 98, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3907, - "end": 3908, + "start": 3338, + "end": 3339, "loc": { "start": { - "line": 115, + "line": 98, "column": 16 }, "end": { - "line": 115, + "line": 98, "column": 17 } }, @@ -12527,43 +10587,43 @@ }, "indexType": { "type": "TSIndexedAccessType", - "start": 3909, - "end": 3913, + "start": 3340, + "end": 3344, "loc": { "start": { - "line": 115, + "line": 98, "column": 18 }, "end": { - "line": 115, + "line": 98, "column": 22 } }, "objectType": { "type": "TSTypeReference", - "start": 3909, - "end": 3910, + "start": 3340, + "end": 3341, "loc": { "start": { - "line": 115, + "line": 98, "column": 18 }, "end": { - "line": 115, + "line": 98, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3909, - "end": 3910, + "start": 3340, + "end": 3341, "loc": { "start": { - "line": 115, + "line": 98, "column": 18 }, "end": { - "line": 115, + "line": 98, "column": 19 } }, @@ -12572,29 +10632,29 @@ }, "indexType": { "type": "TSTypeReference", - "start": 3911, - "end": 3912, + "start": 3342, + "end": 3343, "loc": { "start": { - "line": 115, + "line": 98, "column": 20 }, "end": { - "line": 115, + "line": 98, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 3911, - "end": 3912, + "start": 3342, + "end": 3343, "loc": { "start": { - "line": 115, + "line": 98, "column": 20 }, "end": { - "line": 115, + "line": 98, "column": 21 } }, @@ -12612,44 +10672,44 @@ }, { "type": "VariableDeclaration", - "start": 3920, - "end": 3943, + "start": 3351, + "end": 3374, "loc": { "start": { - "line": 116, + "line": 99, "column": 1 }, "end": { - "line": 116, + "line": 99, "column": 24 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3926, - "end": 3942, + "start": 3357, + "end": 3373, "loc": { "start": { - "line": 116, + "line": 99, "column": 7 }, "end": { - "line": 116, + "line": 99, "column": 23 } }, "id": { "type": "Identifier", - "start": 3926, - "end": 3929, + "start": 3357, + "end": 3360, "loc": { "start": { - "line": 116, + "line": 99, "column": 7 }, "end": { - "line": 116, + "line": 99, "column": 10 } }, @@ -12657,29 +10717,29 @@ }, "init": { "type": "CallExpression", - "start": 3932, - "end": 3942, + "start": 3363, + "end": 3373, "loc": { "start": { - "line": 116, + "line": 99, "column": 13 }, "end": { - "line": 116, + "line": 99, "column": 23 } }, "callee": { "type": "Identifier", - "start": 3932, - "end": 3934, + "start": 3363, + "end": 3365, "loc": { "start": { - "line": 116, + "line": 99, "column": 13 }, "end": { - "line": 116, + "line": 99, "column": 15 } }, @@ -12688,58 +10748,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3934, - "end": 3940, + "start": 3365, + "end": 3371, "loc": { "start": { - "line": 116, + "line": 99, "column": 15 }, "end": { - "line": 116, + "line": 99, "column": 21 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3935, - "end": 3939, + "start": 3366, + "end": 3370, "loc": { "start": { - "line": 116, + "line": 99, "column": 16 }, "end": { - "line": 116, + "line": 99, "column": 20 } }, "objectType": { "type": "TSTypeReference", - "start": 3935, - "end": 3936, + "start": 3366, + "end": 3367, "loc": { "start": { - "line": 116, + "line": 99, "column": 16 }, "end": { - "line": 116, + "line": 99, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3935, - "end": 3936, + "start": 3366, + "end": 3367, "loc": { "start": { - "line": 116, + "line": 99, "column": 16 }, "end": { - "line": 116, + "line": 99, "column": 17 } }, @@ -12748,29 +10808,29 @@ }, "indexType": { "type": "TSLiteralType", - "start": 3937, - "end": 3938, + "start": 3368, + "end": 3369, "loc": { "start": { - "line": 116, + "line": 99, "column": 18 }, "end": { - "line": 116, + "line": 99, "column": 19 } }, "literal": { "type": "Literal", - "start": 3937, - "end": 3938, + "start": 3368, + "end": 3369, "loc": { "start": { - "line": 116, + "line": 99, "column": 18 }, "end": { - "line": 116, + "line": 99, "column": 19 } }, @@ -12788,44 +10848,44 @@ }, { "type": "VariableDeclaration", - "start": 3945, - "end": 3969, + "start": 3376, + "end": 3400, "loc": { "start": { - "line": 117, + "line": 100, "column": 1 }, "end": { - "line": 117, + "line": 100, "column": 25 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3951, - "end": 3968, + "start": 3382, + "end": 3399, "loc": { "start": { - "line": 117, + "line": 100, "column": 7 }, "end": { - "line": 117, + "line": 100, "column": 24 } }, "id": { "type": "Identifier", - "start": 3951, - "end": 3954, + "start": 3382, + "end": 3385, "loc": { "start": { - "line": 117, + "line": 100, "column": 7 }, "end": { - "line": 117, + "line": 100, "column": 10 } }, @@ -12833,29 +10893,29 @@ }, "init": { "type": "CallExpression", - "start": 3957, - "end": 3968, + "start": 3388, + "end": 3399, "loc": { "start": { - "line": 117, + "line": 100, "column": 13 }, "end": { - "line": 117, + "line": 100, "column": 24 } }, "callee": { "type": "Identifier", - "start": 3957, - "end": 3959, + "start": 3388, + "end": 3390, "loc": { "start": { - "line": 117, + "line": 100, "column": 13 }, "end": { - "line": 117, + "line": 100, "column": 15 } }, @@ -12864,58 +10924,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3959, - "end": 3966, + "start": 3390, + "end": 3397, "loc": { "start": { - "line": 117, + "line": 100, "column": 15 }, "end": { - "line": 117, + "line": 100, "column": 22 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3960, - "end": 3965, + "start": 3391, + "end": 3396, "loc": { "start": { - "line": 117, + "line": 100, "column": 16 }, "end": { - "line": 117, + "line": 100, "column": 21 } }, "objectType": { "type": "TSTypeReference", - "start": 3960, - "end": 3961, + "start": 3391, + "end": 3392, "loc": { "start": { - "line": 117, + "line": 100, "column": 16 }, "end": { - "line": 117, + "line": 100, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3960, - "end": 3961, + "start": 3391, + "end": 3392, "loc": { "start": { - "line": 117, + "line": 100, "column": 16 }, "end": { - "line": 117, + "line": 100, "column": 17 } }, @@ -12924,29 +10984,29 @@ }, "indexType": { "type": "TSLiteralType", - "start": 3962, - "end": 3964, + "start": 3393, + "end": 3395, "loc": { "start": { - "line": 117, + "line": 100, "column": 18 }, "end": { - "line": 117, + "line": 100, "column": 20 } }, "literal": { "type": "UnaryExpression", - "start": 3962, - "end": 3964, + "start": 3393, + "end": 3395, "loc": { "start": { - "line": 117, + "line": 100, "column": 18 }, "end": { - "line": 117, + "line": 100, "column": 20 } }, @@ -12954,15 +11014,15 @@ "prefix": true, "argument": { "type": "Literal", - "start": 3963, - "end": 3964, + "start": 3394, + "end": 3395, "loc": { "start": { - "line": 117, + "line": 100, "column": 19 }, "end": { - "line": 117, + "line": 100, "column": 20 } }, @@ -12981,44 +11041,44 @@ }, { "type": "VariableDeclaration", - "start": 3971, - "end": 4012, + "start": 3402, + "end": 3443, "loc": { "start": { - "line": 118, + "line": 101, "column": 1 }, "end": { - "line": 118, + "line": 101, "column": 42 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 3977, - "end": 4011, + "start": 3408, + "end": 3442, "loc": { "start": { - "line": 118, + "line": 101, "column": 7 }, "end": { - "line": 118, + "line": 101, "column": 41 } }, "id": { "type": "Identifier", - "start": 3977, - "end": 3980, + "start": 3408, + "end": 3411, "loc": { "start": { - "line": 118, + "line": 101, "column": 7 }, "end": { - "line": 118, + "line": 101, "column": 10 } }, @@ -13026,29 +11086,29 @@ }, "init": { "type": "CallExpression", - "start": 3983, - "end": 4011, + "start": 3414, + "end": 3442, "loc": { "start": { - "line": 118, + "line": 101, "column": 13 }, "end": { - "line": 118, + "line": 101, "column": 41 } }, "callee": { "type": "Identifier", - "start": 3983, - "end": 3985, + "start": 3414, + "end": 3416, "loc": { "start": { - "line": 118, + "line": 101, "column": 13 }, "end": { - "line": 118, + "line": 101, "column": 15 } }, @@ -13057,58 +11117,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 3985, - "end": 4009, + "start": 3416, + "end": 3440, "loc": { "start": { - "line": 118, + "line": 101, "column": 15 }, "end": { - "line": 118, + "line": 101, "column": 39 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 3986, - "end": 4008, + "start": 3417, + "end": 3439, "loc": { "start": { - "line": 118, + "line": 101, "column": 16 }, "end": { - "line": 118, + "line": 101, "column": 38 } }, "objectType": { "type": "TSTypeReference", - "start": 3986, - "end": 3987, + "start": 3417, + "end": 3418, "loc": { "start": { - "line": 118, + "line": 101, "column": 16 }, "end": { - "line": 118, + "line": 101, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 3986, - "end": 3987, + "start": 3417, + "end": 3418, "loc": { "start": { - "line": 118, + "line": 101, "column": 16 }, "end": { - "line": 118, + "line": 101, "column": 17 } }, @@ -13117,43 +11177,43 @@ }, "indexType": { "type": "TSConditionalType", - "start": 3988, - "end": 4007, + "start": 3419, + "end": 3438, "loc": { "start": { - "line": 118, + "line": 101, "column": 18 }, "end": { - "line": 118, + "line": 101, "column": 37 } }, "checkType": { "type": "TSTypeReference", - "start": 3988, - "end": 3989, + "start": 3419, + "end": 3420, "loc": { "start": { - "line": 118, + "line": 101, "column": 18 }, "end": { - "line": 118, + "line": 101, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 3988, - "end": 3989, + "start": 3419, + "end": 3420, "loc": { "start": { - "line": 118, + "line": 101, "column": 18 }, "end": { - "line": 118, + "line": 101, "column": 19 } }, @@ -13162,29 +11222,29 @@ }, "extendsType": { "type": "TSTypeReference", - "start": 3998, - "end": 3999, + "start": 3429, + "end": 3430, "loc": { "start": { - "line": 118, + "line": 101, "column": 28 }, "end": { - "line": 118, + "line": 101, "column": 29 } }, "typeName": { "type": "Identifier", - "start": 3998, - "end": 3999, + "start": 3429, + "end": 3430, "loc": { "start": { - "line": 118, + "line": 101, "column": 28 }, "end": { - "line": 118, + "line": 101, "column": 29 } }, @@ -13193,29 +11253,29 @@ }, "trueType": { "type": "TSTypeReference", - "start": 4002, - "end": 4003, + "start": 3433, + "end": 3434, "loc": { "start": { - "line": 118, + "line": 101, "column": 32 }, "end": { - "line": 118, + "line": 101, "column": 33 } }, "typeName": { "type": "Identifier", - "start": 4002, - "end": 4003, + "start": 3433, + "end": 3434, "loc": { "start": { - "line": 118, + "line": 101, "column": 32 }, "end": { - "line": 118, + "line": 101, "column": 33 } }, @@ -13224,29 +11284,29 @@ }, "falseType": { "type": "TSTypeReference", - "start": 4006, - "end": 4007, + "start": 3437, + "end": 3438, "loc": { "start": { - "line": 118, + "line": 101, "column": 36 }, "end": { - "line": 118, + "line": 101, "column": 37 } }, "typeName": { "type": "Identifier", - "start": 4006, - "end": 4007, + "start": 3437, + "end": 3438, "loc": { "start": { - "line": 118, + "line": 101, "column": 36 }, "end": { - "line": 118, + "line": 101, "column": 37 } }, @@ -13264,44 +11324,44 @@ }, { "type": "VariableDeclaration", - "start": 4014, - "end": 4039, + "start": 3445, + "end": 3470, "loc": { "start": { - "line": 119, + "line": 102, "column": 1 }, "end": { - "line": 119, + "line": 102, "column": 26 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4020, - "end": 4038, + "start": 3451, + "end": 3469, "loc": { "start": { - "line": 119, + "line": 102, "column": 7 }, "end": { - "line": 119, + "line": 102, "column": 25 } }, "id": { "type": "Identifier", - "start": 4020, - "end": 4023, + "start": 3451, + "end": 3454, "loc": { "start": { - "line": 119, + "line": 102, "column": 7 }, "end": { - "line": 119, + "line": 102, "column": 10 } }, @@ -13309,29 +11369,29 @@ }, "init": { "type": "CallExpression", - "start": 4026, - "end": 4038, + "start": 3457, + "end": 3469, "loc": { "start": { - "line": 119, + "line": 102, "column": 13 }, "end": { - "line": 119, + "line": 102, "column": 25 } }, "callee": { "type": "Identifier", - "start": 4026, - "end": 4028, + "start": 3457, + "end": 3459, "loc": { "start": { - "line": 119, + "line": 102, "column": 13 }, "end": { - "line": 119, + "line": 102, "column": 15 } }, @@ -13340,58 +11400,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4028, - "end": 4036, + "start": 3459, + "end": 3467, "loc": { "start": { - "line": 119, + "line": 102, "column": 15 }, "end": { - "line": 119, + "line": 102, "column": 23 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4029, - "end": 4035, + "start": 3460, + "end": 3466, "loc": { "start": { - "line": 119, + "line": 102, "column": 16 }, "end": { - "line": 119, + "line": 102, "column": 22 } }, "objectType": { "type": "TSTypeReference", - "start": 4029, - "end": 4030, + "start": 3460, + "end": 3461, "loc": { "start": { - "line": 119, + "line": 102, "column": 16 }, "end": { - "line": 119, + "line": 102, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4029, - "end": 4030, + "start": 3460, + "end": 3461, "loc": { "start": { - "line": 119, + "line": 102, "column": 16 }, "end": { - "line": 119, + "line": 102, "column": 17 } }, @@ -13400,43 +11460,43 @@ }, "indexType": { "type": "TSTypeReference", - "start": 4031, - "end": 4034, + "start": 3462, + "end": 3465, "loc": { "start": { - "line": 119, + "line": 102, "column": 18 }, "end": { - "line": 119, + "line": 102, "column": 21 } }, "typeName": { "type": "TSQualifiedName", - "start": 4031, - "end": 4034, + "start": 3462, + "end": 3465, "loc": { "start": { - "line": 119, + "line": 102, "column": 18 }, "end": { - "line": 119, + "line": 102, "column": 21 } }, "left": { "type": "Identifier", - "start": 4031, - "end": 4032, + "start": 3462, + "end": 3463, "loc": { "start": { - "line": 119, + "line": 102, "column": 18 }, "end": { - "line": 119, + "line": 102, "column": 19 } }, @@ -13444,15 +11504,15 @@ }, "right": { "type": "Identifier", - "start": 4033, - "end": 4034, + "start": 3464, + "end": 3465, "loc": { "start": { - "line": 119, + "line": 102, "column": 20 }, "end": { - "line": 119, + "line": 102, "column": 21 } }, @@ -13470,44 +11530,44 @@ }, { "type": "VariableDeclaration", - "start": 4041, - "end": 4069, + "start": 3472, + "end": 3500, "loc": { "start": { - "line": 120, + "line": 103, "column": 1 }, "end": { - "line": 120, + "line": 103, "column": 29 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4047, - "end": 4068, + "start": 3478, + "end": 3499, "loc": { "start": { - "line": 120, + "line": 103, "column": 7 }, "end": { - "line": 120, + "line": 103, "column": 28 } }, "id": { "type": "Identifier", - "start": 4047, - "end": 4050, + "start": 3478, + "end": 3481, "loc": { "start": { - "line": 120, + "line": 103, "column": 7 }, "end": { - "line": 120, + "line": 103, "column": 10 } }, @@ -13515,29 +11575,29 @@ }, "init": { "type": "CallExpression", - "start": 4053, - "end": 4068, + "start": 3484, + "end": 3499, "loc": { "start": { - "line": 120, + "line": 103, "column": 13 }, "end": { - "line": 120, + "line": 103, "column": 28 } }, "callee": { "type": "Identifier", - "start": 4053, - "end": 4055, + "start": 3484, + "end": 3486, "loc": { "start": { - "line": 120, + "line": 103, "column": 13 }, "end": { - "line": 120, + "line": 103, "column": 15 } }, @@ -13546,58 +11606,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4055, - "end": 4066, + "start": 3486, + "end": 3497, "loc": { "start": { - "line": 120, + "line": 103, "column": 15 }, "end": { - "line": 120, + "line": 103, "column": 26 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4056, - "end": 4065, + "start": 3487, + "end": 3496, "loc": { "start": { - "line": 120, + "line": 103, "column": 16 }, "end": { - "line": 120, + "line": 103, "column": 25 } }, "objectType": { "type": "TSTypeReference", - "start": 4056, - "end": 4057, + "start": 3487, + "end": 3488, "loc": { "start": { - "line": 120, + "line": 103, "column": 16 }, "end": { - "line": 120, + "line": 103, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4056, - "end": 4057, + "start": 3487, + "end": 3488, "loc": { "start": { - "line": 120, + "line": 103, "column": 16 }, "end": { - "line": 120, + "line": 103, "column": 17 } }, @@ -13606,43 +11666,43 @@ }, "indexType": { "type": "TSIndexedAccessType", - "start": 4058, - "end": 4064, + "start": 3489, + "end": 3495, "loc": { "start": { - "line": 120, + "line": 103, "column": 18 }, "end": { - "line": 120, + "line": 103, "column": 24 } }, "objectType": { "type": "TSTypeReference", - "start": 4058, - "end": 4059, + "start": 3489, + "end": 3490, "loc": { "start": { - "line": 120, + "line": 103, "column": 18 }, "end": { - "line": 120, + "line": 103, "column": 19 } }, "typeName": { "type": "Identifier", - "start": 4058, - "end": 4059, + "start": 3489, + "end": 3490, "loc": { "start": { - "line": 120, + "line": 103, "column": 18 }, "end": { - "line": 120, + "line": 103, "column": 19 } }, @@ -13651,29 +11711,29 @@ }, "indexType": { "type": "TSLiteralType", - "start": 4060, - "end": 4063, + "start": 3491, + "end": 3494, "loc": { "start": { - "line": 120, + "line": 103, "column": 20 }, "end": { - "line": 120, + "line": 103, "column": 23 } }, "literal": { "type": "Literal", - "start": 4060, - "end": 4063, + "start": 3491, + "end": 3494, "loc": { "start": { - "line": 120, + "line": 103, "column": 20 }, "end": { - "line": 120, + "line": 103, "column": 23 } }, @@ -13692,44 +11752,44 @@ }, { "type": "VariableDeclaration", - "start": 4071, - "end": 4097, + "start": 3502, + "end": 3528, "loc": { "start": { - "line": 121, + "line": 104, "column": 1 }, "end": { - "line": 121, + "line": 104, "column": 27 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4077, - "end": 4096, + "start": 3508, + "end": 3527, "loc": { "start": { - "line": 121, + "line": 104, "column": 7 }, "end": { - "line": 121, + "line": 104, "column": 26 } }, "id": { "type": "Identifier", - "start": 4077, - "end": 4080, + "start": 3508, + "end": 3511, "loc": { "start": { - "line": 121, + "line": 104, "column": 7 }, "end": { - "line": 121, + "line": 104, "column": 10 } }, @@ -13737,29 +11797,29 @@ }, "init": { "type": "CallExpression", - "start": 4083, - "end": 4096, + "start": 3514, + "end": 3527, "loc": { "start": { - "line": 121, + "line": 104, "column": 13 }, "end": { - "line": 121, + "line": 104, "column": 26 } }, "callee": { "type": "Identifier", - "start": 4083, - "end": 4085, + "start": 3514, + "end": 3516, "loc": { "start": { - "line": 121, + "line": 104, "column": 13 }, "end": { - "line": 121, + "line": 104, "column": 15 } }, @@ -13768,58 +11828,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4085, - "end": 4094, + "start": 3516, + "end": 3525, "loc": { "start": { - "line": 121, + "line": 104, "column": 15 }, "end": { - "line": 121, + "line": 104, "column": 24 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4086, - "end": 4093, + "start": 3517, + "end": 3524, "loc": { "start": { - "line": 121, + "line": 104, "column": 16 }, "end": { - "line": 121, + "line": 104, "column": 23 } }, "objectType": { "type": "TSTypeReference", - "start": 4086, - "end": 4087, + "start": 3517, + "end": 3518, "loc": { "start": { - "line": 121, + "line": 104, "column": 16 }, "end": { - "line": 121, + "line": 104, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4086, - "end": 4087, + "start": 3517, + "end": 3518, "loc": { "start": { - "line": 121, + "line": 104, "column": 16 }, "end": { - "line": 121, + "line": 104, "column": 17 } }, @@ -13828,29 +11888,29 @@ }, "indexType": { "type": "TSTypeReference", - "start": 4088, - "end": 4092, + "start": 3519, + "end": 3523, "loc": { "start": { - "line": 121, + "line": 104, "column": 18 }, "end": { - "line": 121, + "line": 104, "column": 22 } }, "typeName": { "type": "Identifier", - "start": 4088, - "end": 4089, + "start": 3519, + "end": 3520, "loc": { "start": { - "line": 121, + "line": 104, "column": 18 }, "end": { - "line": 121, + "line": 104, "column": 19 } }, @@ -13858,44 +11918,44 @@ }, "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4089, - "end": 4092, + "start": 3520, + "end": 3523, "loc": { "start": { - "line": 121, + "line": 104, "column": 19 }, "end": { - "line": 121, + "line": 104, "column": 22 } }, "params": [ { "type": "TSTypeReference", - "start": 4090, - "end": 4091, + "start": 3521, + "end": 3522, "loc": { "start": { - "line": 121, + "line": 104, "column": 20 }, "end": { - "line": 121, + "line": 104, "column": 21 } }, "typeName": { "type": "Identifier", - "start": 4090, - "end": 4091, + "start": 3521, + "end": 3522, "loc": { "start": { - "line": 121, + "line": 104, "column": 20 }, "end": { - "line": 121, + "line": 104, "column": 21 } }, @@ -13915,44 +11975,44 @@ }, { "type": "VariableDeclaration", - "start": 4341, - "end": 4368, + "start": 3772, + "end": 3799, "loc": { "start": { - "line": 126, + "line": 109, "column": 1 }, "end": { - "line": 126, + "line": 109, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4347, - "end": 4367, + "start": 3778, + "end": 3798, "loc": { "start": { - "line": 126, + "line": 109, "column": 7 }, "end": { - "line": 126, + "line": 109, "column": 27 } }, "id": { "type": "Identifier", - "start": 4347, - "end": 4350, + "start": 3778, + "end": 3781, "loc": { "start": { - "line": 126, + "line": 109, "column": 7 }, "end": { - "line": 126, + "line": 109, "column": 10 } }, @@ -13960,29 +12020,29 @@ }, "init": { "type": "CallExpression", - "start": 4353, - "end": 4367, + "start": 3784, + "end": 3798, "loc": { "start": { - "line": 126, + "line": 109, "column": 13 }, "end": { - "line": 126, + "line": 109, "column": 27 } }, "callee": { "type": "Identifier", - "start": 4353, - "end": 4355, + "start": 3784, + "end": 3786, "loc": { "start": { - "line": 126, + "line": 109, "column": 13 }, "end": { - "line": 126, + "line": 109, "column": 15 } }, @@ -13991,58 +12051,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4355, - "end": 4365, + "start": 3786, + "end": 3796, "loc": { "start": { - "line": 126, + "line": 109, "column": 15 }, "end": { - "line": 126, + "line": 109, "column": 25 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4356, - "end": 4364, + "start": 3787, + "end": 3795, "loc": { "start": { - "line": 126, + "line": 109, "column": 16 }, "end": { - "line": 126, + "line": 109, "column": 24 } }, "objectType": { "type": "TSTypeReference", - "start": 4356, - "end": 4357, + "start": 3787, + "end": 3788, "loc": { "start": { - "line": 126, + "line": 109, "column": 16 }, "end": { - "line": 126, + "line": 109, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4356, - "end": 4357, + "start": 3787, + "end": 3788, "loc": { "start": { - "line": 126, + "line": 109, "column": 16 }, "end": { - "line": 126, + "line": 109, "column": 17 } }, @@ -14051,44 +12111,44 @@ }, "indexType": { "type": "TSUnionType", - "start": 4358, - "end": 4363, + "start": 3789, + "end": 3794, "loc": { "start": { - "line": 126, + "line": 109, "column": 18 }, "end": { - "line": 126, + "line": 109, "column": 23 } }, "types": [ { "type": "TSLiteralType", - "start": 4358, - "end": 4359, + "start": 3789, + "end": 3790, "loc": { "start": { - "line": 126, + "line": 109, "column": 18 }, "end": { - "line": 126, + "line": 109, "column": 19 } }, "literal": { "type": "Literal", - "start": 4358, - "end": 4359, + "start": 3789, + "end": 3790, "loc": { "start": { - "line": 126, + "line": 109, "column": 18 }, "end": { - "line": 126, + "line": 109, "column": 19 } }, @@ -14098,29 +12158,29 @@ }, { "type": "TSLiteralType", - "start": 4362, - "end": 4363, + "start": 3793, + "end": 3794, "loc": { "start": { - "line": 126, + "line": 109, "column": 22 }, "end": { - "line": 126, + "line": 109, "column": 23 } }, "literal": { "type": "Literal", - "start": 4362, - "end": 4363, + "start": 3793, + "end": 3794, "loc": { "start": { - "line": 126, + "line": 109, "column": 22 }, "end": { - "line": 126, + "line": 109, "column": 23 } }, @@ -14141,63 +12201,63 @@ { "type": "Line", "value": " a numeric literal index continues into a type exactly as a reference index does —", - "start": 4100, - "end": 4184 + "start": 3531, + "end": 3615 }, { "type": "Line", "value": " union, intersection, and conditional forms are type arguments whichever operand", - "start": 4186, - "end": 4268 + "start": 3617, + "end": 3699 }, { "type": "Line", "value": " kind opens them, and an exponent's own sign belongs to the literal", - "start": 4270, - "end": 4339 + "start": 3701, + "end": 3770 } ] }, { "type": "VariableDeclaration", - "start": 4370, - "end": 4399, + "start": 3801, + "end": 3830, "loc": { "start": { - "line": 127, + "line": 110, "column": 1 }, "end": { - "line": 127, + "line": 110, "column": 30 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4376, - "end": 4398, + "start": 3807, + "end": 3829, "loc": { "start": { - "line": 127, + "line": 110, "column": 7 }, "end": { - "line": 127, + "line": 110, "column": 29 } }, "id": { "type": "Identifier", - "start": 4376, - "end": 4379, + "start": 3807, + "end": 3810, "loc": { "start": { - "line": 127, + "line": 110, "column": 7 }, "end": { - "line": 127, + "line": 110, "column": 10 } }, @@ -14205,29 +12265,29 @@ }, "init": { "type": "CallExpression", - "start": 4382, - "end": 4398, + "start": 3813, + "end": 3829, "loc": { "start": { - "line": 127, + "line": 110, "column": 13 }, "end": { - "line": 127, + "line": 110, "column": 29 } }, "callee": { "type": "Identifier", - "start": 4382, - "end": 4384, + "start": 3813, + "end": 3815, "loc": { "start": { - "line": 127, + "line": 110, "column": 13 }, "end": { - "line": 127, + "line": 110, "column": 15 } }, @@ -14236,58 +12296,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4384, - "end": 4396, + "start": 3815, + "end": 3827, "loc": { "start": { - "line": 127, + "line": 110, "column": 15 }, "end": { - "line": 127, + "line": 110, "column": 27 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4385, - "end": 4395, + "start": 3816, + "end": 3826, "loc": { "start": { - "line": 127, + "line": 110, "column": 16 }, "end": { - "line": 127, + "line": 110, "column": 26 } }, "objectType": { "type": "TSTypeReference", - "start": 4385, - "end": 4386, + "start": 3816, + "end": 3817, "loc": { "start": { - "line": 127, + "line": 110, "column": 16 }, "end": { - "line": 127, + "line": 110, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4385, - "end": 4386, + "start": 3816, + "end": 3817, "loc": { "start": { - "line": 127, + "line": 110, "column": 16 }, "end": { - "line": 127, + "line": 110, "column": 17 } }, @@ -14296,44 +12356,44 @@ }, "indexType": { "type": "TSUnionType", - "start": 4387, - "end": 4394, + "start": 3818, + "end": 3825, "loc": { "start": { - "line": 127, + "line": 110, "column": 18 }, "end": { - "line": 127, + "line": 110, "column": 25 } }, "types": [ { "type": "TSLiteralType", - "start": 4387, - "end": 4389, + "start": 3818, + "end": 3820, "loc": { "start": { - "line": 127, + "line": 110, "column": 18 }, "end": { - "line": 127, + "line": 110, "column": 20 } }, "literal": { "type": "UnaryExpression", - "start": 4387, - "end": 4389, + "start": 3818, + "end": 3820, "loc": { "start": { - "line": 127, + "line": 110, "column": 18 }, "end": { - "line": 127, + "line": 110, "column": 20 } }, @@ -14341,15 +12401,15 @@ "prefix": true, "argument": { "type": "Literal", - "start": 4388, - "end": 4389, + "start": 3819, + "end": 3820, "loc": { "start": { - "line": 127, + "line": 110, "column": 19 }, "end": { - "line": 127, + "line": 110, "column": 20 } }, @@ -14360,29 +12420,29 @@ }, { "type": "TSLiteralType", - "start": 4392, - "end": 4394, + "start": 3823, + "end": 3825, "loc": { "start": { - "line": 127, + "line": 110, "column": 23 }, "end": { - "line": 127, + "line": 110, "column": 25 } }, "literal": { "type": "UnaryExpression", - "start": 4392, - "end": 4394, + "start": 3823, + "end": 3825, "loc": { "start": { - "line": 127, + "line": 110, "column": 23 }, "end": { - "line": 127, + "line": 110, "column": 25 } }, @@ -14390,15 +12450,15 @@ "prefix": true, "argument": { "type": "Literal", - "start": 4393, - "end": 4394, + "start": 3824, + "end": 3825, "loc": { "start": { - "line": 127, + "line": 110, "column": 24 }, "end": { - "line": 127, + "line": 110, "column": 25 } }, @@ -14419,44 +12479,44 @@ }, { "type": "VariableDeclaration", - "start": 4401, - "end": 4428, + "start": 3832, + "end": 3859, "loc": { "start": { - "line": 128, + "line": 111, "column": 1 }, "end": { - "line": 128, + "line": 111, "column": 28 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4407, - "end": 4427, + "start": 3838, + "end": 3858, "loc": { "start": { - "line": 128, + "line": 111, "column": 7 }, "end": { - "line": 128, + "line": 111, "column": 27 } }, "id": { "type": "Identifier", - "start": 4407, - "end": 4410, + "start": 3838, + "end": 3841, "loc": { "start": { - "line": 128, + "line": 111, "column": 7 }, "end": { - "line": 128, + "line": 111, "column": 10 } }, @@ -14464,29 +12524,29 @@ }, "init": { "type": "CallExpression", - "start": 4413, - "end": 4427, + "start": 3844, + "end": 3858, "loc": { "start": { - "line": 128, + "line": 111, "column": 13 }, "end": { - "line": 128, + "line": 111, "column": 27 } }, "callee": { "type": "Identifier", - "start": 4413, - "end": 4415, + "start": 3844, + "end": 3846, "loc": { "start": { - "line": 128, + "line": 111, "column": 13 }, "end": { - "line": 128, + "line": 111, "column": 15 } }, @@ -14495,58 +12555,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4415, - "end": 4425, + "start": 3846, + "end": 3856, "loc": { "start": { - "line": 128, + "line": 111, "column": 15 }, "end": { - "line": 128, + "line": 111, "column": 25 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4416, - "end": 4424, + "start": 3847, + "end": 3855, "loc": { "start": { - "line": 128, + "line": 111, "column": 16 }, "end": { - "line": 128, + "line": 111, "column": 24 } }, "objectType": { "type": "TSTypeReference", - "start": 4416, - "end": 4417, + "start": 3847, + "end": 3848, "loc": { "start": { - "line": 128, + "line": 111, "column": 16 }, "end": { - "line": 128, + "line": 111, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4416, - "end": 4417, + "start": 3847, + "end": 3848, "loc": { "start": { - "line": 128, + "line": 111, "column": 16 }, "end": { - "line": 128, + "line": 111, "column": 17 } }, @@ -14555,44 +12615,44 @@ }, "indexType": { "type": "TSIntersectionType", - "start": 4418, - "end": 4423, + "start": 3849, + "end": 3854, "loc": { "start": { - "line": 128, + "line": 111, "column": 18 }, "end": { - "line": 128, + "line": 111, "column": 23 } }, "types": [ { "type": "TSLiteralType", - "start": 4418, - "end": 4419, + "start": 3849, + "end": 3850, "loc": { "start": { - "line": 128, + "line": 111, "column": 18 }, "end": { - "line": 128, + "line": 111, "column": 19 } }, "literal": { "type": "Literal", - "start": 4418, - "end": 4419, + "start": 3849, + "end": 3850, "loc": { "start": { - "line": 128, + "line": 111, "column": 18 }, "end": { - "line": 128, + "line": 111, "column": 19 } }, @@ -14602,29 +12662,29 @@ }, { "type": "TSLiteralType", - "start": 4422, - "end": 4423, + "start": 3853, + "end": 3854, "loc": { "start": { - "line": 128, + "line": 111, "column": 22 }, "end": { - "line": 128, + "line": 111, "column": 23 } }, "literal": { "type": "Literal", - "start": 4422, - "end": 4423, + "start": 3853, + "end": 3854, "loc": { "start": { - "line": 128, + "line": 111, "column": 22 }, "end": { - "line": 128, + "line": 111, "column": 23 } }, @@ -14644,44 +12704,44 @@ }, { "type": "VariableDeclaration", - "start": 4430, - "end": 4460, + "start": 3861, + "end": 3891, "loc": { "start": { - "line": 129, + "line": 112, "column": 1 }, "end": { - "line": 129, + "line": 112, "column": 31 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4436, - "end": 4459, + "start": 3867, + "end": 3890, "loc": { "start": { - "line": 129, + "line": 112, "column": 7 }, "end": { - "line": 129, + "line": 112, "column": 30 } }, "id": { "type": "Identifier", - "start": 4436, - "end": 4439, + "start": 3867, + "end": 3870, "loc": { "start": { - "line": 129, + "line": 112, "column": 7 }, "end": { - "line": 129, + "line": 112, "column": 10 } }, @@ -14689,29 +12749,29 @@ }, "init": { "type": "CallExpression", - "start": 4442, - "end": 4459, + "start": 3873, + "end": 3890, "loc": { "start": { - "line": 129, + "line": 112, "column": 13 }, "end": { - "line": 129, + "line": 112, "column": 30 } }, "callee": { "type": "Identifier", - "start": 4442, - "end": 4444, + "start": 3873, + "end": 3875, "loc": { "start": { - "line": 129, + "line": 112, "column": 13 }, "end": { - "line": 129, + "line": 112, "column": 15 } }, @@ -14720,58 +12780,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4444, - "end": 4457, + "start": 3875, + "end": 3888, "loc": { "start": { - "line": 129, + "line": 112, "column": 15 }, "end": { - "line": 129, + "line": 112, "column": 28 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4445, - "end": 4456, + "start": 3876, + "end": 3887, "loc": { "start": { - "line": 129, + "line": 112, "column": 16 }, "end": { - "line": 129, + "line": 112, "column": 27 } }, "objectType": { "type": "TSTypeReference", - "start": 4445, - "end": 4446, + "start": 3876, + "end": 3877, "loc": { "start": { - "line": 129, + "line": 112, "column": 16 }, "end": { - "line": 129, + "line": 112, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4445, - "end": 4446, + "start": 3876, + "end": 3877, "loc": { "start": { - "line": 129, + "line": 112, "column": 16 }, "end": { - "line": 129, + "line": 112, "column": 17 } }, @@ -14780,44 +12840,44 @@ }, "indexType": { "type": "TSUnionType", - "start": 4447, - "end": 4455, + "start": 3878, + "end": 3886, "loc": { "start": { - "line": 129, + "line": 112, "column": 18 }, "end": { - "line": 129, + "line": 112, "column": 26 } }, "types": [ { "type": "TSLiteralType", - "start": 4447, - "end": 4451, + "start": 3878, + "end": 3882, "loc": { "start": { - "line": 129, + "line": 112, "column": 18 }, "end": { - "line": 129, + "line": 112, "column": 22 } }, "literal": { "type": "Literal", - "start": 4447, - "end": 4451, + "start": 3878, + "end": 3882, "loc": { "start": { - "line": 129, + "line": 112, "column": 18 }, "end": { - "line": 129, + "line": 112, "column": 22 } }, @@ -14827,29 +12887,29 @@ }, { "type": "TSLiteralType", - "start": 4454, - "end": 4455, + "start": 3885, + "end": 3886, "loc": { "start": { - "line": 129, + "line": 112, "column": 25 }, "end": { - "line": 129, + "line": 112, "column": 26 } }, "literal": { "type": "Literal", - "start": 4454, - "end": 4455, + "start": 3885, + "end": 3886, "loc": { "start": { - "line": 129, + "line": 112, "column": 25 }, "end": { - "line": 129, + "line": 112, "column": 26 } }, @@ -14869,44 +12929,44 @@ }, { "type": "VariableDeclaration", - "start": 4462, - "end": 4503, + "start": 3893, + "end": 3934, "loc": { "start": { - "line": 130, + "line": 113, "column": 1 }, "end": { - "line": 130, + "line": 113, "column": 42 } }, "declarations": [ { "type": "VariableDeclarator", - "start": 4468, - "end": 4502, + "start": 3899, + "end": 3933, "loc": { "start": { - "line": 130, + "line": 113, "column": 7 }, "end": { - "line": 130, + "line": 113, "column": 41 } }, "id": { "type": "Identifier", - "start": 4468, - "end": 4471, + "start": 3899, + "end": 3902, "loc": { "start": { - "line": 130, + "line": 113, "column": 7 }, "end": { - "line": 130, + "line": 113, "column": 10 } }, @@ -14914,29 +12974,29 @@ }, "init": { "type": "CallExpression", - "start": 4474, - "end": 4502, + "start": 3905, + "end": 3933, "loc": { "start": { - "line": 130, + "line": 113, "column": 13 }, "end": { - "line": 130, + "line": 113, "column": 41 } }, "callee": { "type": "Identifier", - "start": 4474, - "end": 4476, + "start": 3905, + "end": 3907, "loc": { "start": { - "line": 130, + "line": 113, "column": 13 }, "end": { - "line": 130, + "line": 113, "column": 15 } }, @@ -14945,58 +13005,58 @@ "arguments": [], "typeArguments": { "type": "TSTypeParameterInstantiation", - "start": 4476, - "end": 4500, + "start": 3907, + "end": 3931, "loc": { "start": { - "line": 130, + "line": 113, "column": 15 }, "end": { - "line": 130, + "line": 113, "column": 39 } }, "params": [ { "type": "TSIndexedAccessType", - "start": 4477, - "end": 4499, + "start": 3908, + "end": 3930, "loc": { "start": { - "line": 130, + "line": 113, "column": 16 }, "end": { - "line": 130, + "line": 113, "column": 38 } }, "objectType": { "type": "TSTypeReference", - "start": 4477, - "end": 4478, + "start": 3908, + "end": 3909, "loc": { "start": { - "line": 130, + "line": 113, "column": 16 }, "end": { - "line": 130, + "line": 113, "column": 17 } }, "typeName": { "type": "Identifier", - "start": 4477, - "end": 4478, + "start": 3908, + "end": 3909, "loc": { "start": { - "line": 130, + "line": 113, "column": 16 }, "end": { - "line": 130, + "line": 113, "column": 17 } }, @@ -15005,43 +13065,43 @@ }, "indexType": { "type": "TSConditionalType", - "start": 4479, - "end": 4498, + "start": 3910, + "end": 3929, "loc": { "start": { - "line": 130, + "line": 113, "column": 18 }, "end": { - "line": 130, + "line": 113, "column": 37 } }, "checkType": { "type": "TSLiteralType", - "start": 4479, - "end": 4480, + "start": 3910, + "end": 3911, "loc": { "start": { - "line": 130, + "line": 113, "column": 18 }, "end": { - "line": 130, + "line": 113, "column": 19 } }, "literal": { "type": "Literal", - "start": 4479, - "end": 4480, + "start": 3910, + "end": 3911, "loc": { "start": { - "line": 130, + "line": 113, "column": 18 }, "end": { - "line": 130, + "line": 113, "column": 19 } }, @@ -15051,29 +13111,29 @@ }, "extendsType": { "type": "TSLiteralType", - "start": 4489, - "end": 4490, + "start": 3920, + "end": 3921, "loc": { "start": { - "line": 130, + "line": 113, "column": 28 }, "end": { - "line": 130, + "line": 113, "column": 29 } }, "literal": { "type": "Literal", - "start": 4489, - "end": 4490, + "start": 3920, + "end": 3921, "loc": { "start": { - "line": 130, + "line": 113, "column": 28 }, "end": { - "line": 130, + "line": 113, "column": 29 } }, @@ -15083,29 +13143,29 @@ }, "trueType": { "type": "TSTypeReference", - "start": 4493, - "end": 4494, + "start": 3924, + "end": 3925, "loc": { "start": { - "line": 130, + "line": 113, "column": 32 }, "end": { - "line": 130, + "line": 113, "column": 33 } }, "typeName": { "type": "Identifier", - "start": 4493, - "end": 4494, + "start": 3924, + "end": 3925, "loc": { "start": { - "line": 130, + "line": 113, "column": 32 }, "end": { - "line": 130, + "line": 113, "column": 33 } }, @@ -15114,29 +13174,29 @@ }, "falseType": { "type": "TSTypeReference", - "start": 4497, - "end": 4498, + "start": 3928, + "end": 3929, "loc": { "start": { - "line": 130, + "line": 113, "column": 36 }, "end": { - "line": 130, + "line": 113, "column": 37 } }, "typeName": { "type": "Identifier", - "start": 4497, - "end": 4498, + "start": 3928, + "end": 3929, "loc": { "start": { - "line": 130, + "line": 113, "column": 36 }, "end": { - "line": 130, + "line": 113, "column": 37 } }, diff --git a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/input.svelte b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/input.svelte index e2fb9c295..ab2854663 100644 --- a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/input.svelte +++ b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/input.svelte @@ -8,11 +8,8 @@ const a6 = x < { a: 1 }; const a7 = x < [1]; - // a closing `>` followed by an identifier is a chained comparison, not type args; - // this holds across string, numeric, and bare-identifier operands - const a8 = x < 'b' > c; - const a9 = x < 1 > c; - const a10 = a < b > c; + // a second `<` after the operand opens no nested list — nothing closes one, so the + // line is a chained comparison const a11 = a < b < c; // a parenthesized ternary operand is a comparison, not a `(b?: T) => ...` function type @@ -21,19 +18,6 @@ // a `>` inside an array literal belongs to the array, not the relational chain const a13 = x < [a > b]; - // any expression-starting token after the closing `>` makes it a comparison - // chain too — literal, unary, array, and object operands behave like the - // identifier and typeof operands - const a14 = x < y > 1; - const a15 = x < y > 'b'; - const a16 = x < y > !c; - const a17 = x < y > ~c; - const a18 = x < y > -1; - const a19 = x < y > +1; - const a20 = x < y > [0]; - const a21 = x < y > { a: 1 }; - const a22 = x < y > typeof c; - // an indexed member access after `<` is a comparison operand, not an indexed access // type; the `,` that follows it belongs to the enclosing argument, element, or // property list, whatever the index is @@ -64,9 +48,8 @@ const a34 = a < B[0 || 1] > c; const a35 = a < B[0 <= 1] > c; - // a `>` or a shift operator after the indexed operand continues the comparison - // chain — the `>` run belongs to the operator, not to a type-argument close - const a28 = a < B[c] > d; + // a shift operator after the indexed operand continues the comparison chain — the + // `>` run belongs to the operator, not to a type-argument close const a29 = a < B[c] >> d; const a30 = a < B[c] >>> d; diff --git a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_asi.svelte b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_asi.svelte index ed95335fd..b35c2e2e8 100644 --- a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_asi.svelte +++ b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_asi.svelte @@ -8,11 +8,8 @@ const a6 = x < { a: 1 }; const a7 = x < [1]; - // a closing `>` followed by an identifier is a chained comparison, not type args; - // this holds across string, numeric, and bare-identifier operands - const a8 = x < 'b' > c; - const a9 = x < 1 > c; - const a10 = a < b > c; + // a second `<` after the operand opens no nested list — nothing closes one, so the + // line is a chained comparison const a11 = a < b < c; // a parenthesized ternary operand is a comparison, not a `(b?: T) => ...` function type @@ -21,19 +18,6 @@ // a `>` inside an array literal belongs to the array, not the relational chain const a13 = x < [a > b]; - // any expression-starting token after the closing `>` makes it a comparison - // chain too — literal, unary, array, and object operands behave like the - // identifier and typeof operands - const a14 = x < y > 1; - const a15 = x < y > 'b'; - const a16 = x < y > !c; - const a17 = x < y > ~c; - const a18 = x < y > -1; - const a19 = x < y > +1; - const a20 = x < y > [0]; - const a21 = x < y > { a: 1 }; - const a22 = x < y > typeof c; - // an indexed member access after `<` is a comparison operand, not an indexed access // type; the `,` that follows it belongs to the enclosing argument, element, or // property list, whatever the index is @@ -64,9 +48,8 @@ const a34 = a < B[0 || 1] > c; const a35 = a < B[0 <= 1] > c; - // a `>` or a shift operator after the indexed operand continues the comparison - // chain — the `>` run belongs to the operator, not to a type-argument close - const a28 = a < B[c] > d; + // a shift operator after the indexed operand continues the comparison chain — the + // `>` run belongs to the operator, not to a type-argument close const a29 = a < B[c] >> d; const a30 = a < B[c] >>> d; diff --git a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_compact.svelte b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_compact.svelte index 135f6916e..022f8ab33 100644 --- a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_compact.svelte +++ b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_compact.svelte @@ -8,11 +8,8 @@ const a6=x<{a:1}; const a7=x<[1]; - // a closing `>` followed by an identifier is a chained comparison, not type args; - // this holds across string, numeric, and bare-identifier operands - const a8=x<'b'>c; - const a9=x<1>c; - const a10=ac; + // a second `<` after the operand opens no nested list — nothing closes one, so the + // line is a chained comparison const a11=a ...` function type @@ -21,19 +18,6 @@ // a `>` inside an array literal belongs to the array, not the relational chain const a13=x<[a>b]; - // any expression-starting token after the closing `>` makes it a comparison - // chain too — literal, unary, array, and object operands behave like the - // identifier and typeof operands - const a14=x1; - const a15=x'b'; - const a16=x!c; - const a17=x~c; - const a18=x-1; - const a19=x+1; - const a20=x[0]; - const a21=x{a:1}; - const a22=xtypeof c; - // an indexed member access after `<` is a comparison operand, not an indexed access // type; the `,` that follows it belongs to the enclosing argument, element, or // property list, whatever the index is @@ -64,9 +48,8 @@ const a34=a(c); const a35=a(c); - // a `>` or a shift operator after the indexed operand continues the comparison - // chain — the `>` run belongs to the operator, not to a type-argument close - const a28=ad; + // a shift operator after the indexed operand continues the comparison chain — the + // `>` run belongs to the operator, not to a type-argument close const a29=a>d; const a30=a>>d; diff --git a/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_operand_shell.svelte b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_operand_shell.svelte new file mode 100644 index 000000000..40457468d --- /dev/null +++ b/tests/fixtures/typescript/expressions/binary/relational_lt_vs_type_args/unformatted_operand_shell.svelte @@ -0,0 +1,114 @@ + diff --git a/tests/instantiation_follow_parens.rs b/tests/instantiation_follow_parens.rs index c0f58de10..ce455f1e3 100644 --- a/tests/instantiation_follow_parens.rs +++ b/tests/instantiation_follow_parens.rs @@ -19,8 +19,16 @@ //! //! `fn + 1` and `fn - 1` are the CONTRAST that bounds the repair class, and they are //! unfixturable for the opposite reason: both parsers accept them, as a relational chain -//! (`fn < T > +1`), so tsv prints that chain instead of repairing anything. A variant -//! must normalize to its `input.*`, and a third form is not its input. +//! (`fn < T > +1`), so the instantiation rule has nothing to repair — the input was never an +//! instantiation. A variant must normalize to its `input.*`, and a third form is not its +//! input. What tsv prints is that chain with a pair around the `<` operand — the SEPARATE +//! relational-chain rule, which is the contrast's whole point: the pair lands around the +//! chain's left operand, never around the instantiation the tail rule would have wrapped. +//! That rule fires here because tsv's own parse, like acorn-typescript, reads `fn < T >⏎+1` +//! as `(fn) + 1`, so a bare chain would re-lex once a break lands past the `>`. tsc would +//! not, so this pair is owed to tsv's reparse of its own output rather than to tsc (which +//! followers commit, for each parser, is stated in `docs/conformance_prettier_ts.md` +//! §Relational chain type-argument parens). //! //! The followers the two parsers BOTH reject are the class's far edge — no repair to make, //! so tsv matching acorn is the drop-in contract rather than an over-rejection. They are @@ -66,15 +74,23 @@ fn what_the_canonical_parser_rejects_gets_the_pair_back() { fn a_follower_that_re_lexes_is_not_repaired() { // A `+` or `-` continues a comparison chain, so the bare spelling is not a mis-spelled // instantiation at all — it is a different program, and tsv prints the program it - // parsed rather than inventing a pair. + // parsed. The pair it prints is the RELATIONAL-chain one, around the `<` operand, not + // the instantiation pair this file's other case is about: tsv's own parse reads + // `fn < T >⏎+1` as `fn + 1`, so the chain would re-lex the moment a break lands past + // the `>` (tsc would keep the chain there; see the module docs). The two pairs are in + // different places, and which one appears is the assertion. for (bare, printed) in [ - ("const a = fn + 1;\n", "const a = fn < T > +1;\n"), - ("const b = fn - 1;\n", "const b = fn < T > -1;\n"), + ("const a = fn + 1;\n", "const a = (fn < T) > +1;\n"), + ("const b = fn - 1;\n", "const b = (fn < T) > -1;\n"), ] { assert_eq!( format(bare), printed, "a re-lexed follower keeps its reading" ); + assert!( + parses(&format(bare)), + "the printed chain must reparse: {bare}" + ); } }