diff --git a/extensions/oc-path/src/oc-path/find.ts b/extensions/oc-path/src/oc-path/find.ts index 3b95d907273..8de819c8053 100644 --- a/extensions/oc-path/src/oc-path/find.ts +++ b/extensions/oc-path/src/oc-path/find.ts @@ -11,6 +11,7 @@ import { isMap, isScalar, isSeq, type Node, type Pair } from "yaml"; import type { MdAst } from "./ast.js"; import type { JsoncValue } from "./jsonc/ast.js"; import type { JsonlAst, JsonlLine } from "./jsonl/ast.js"; +import { pickJsonlLine } from "./jsonl/line.js"; import type { OcPath } from "./oc-path.js"; import { MAX_TRAVERSAL_DEPTH, @@ -364,7 +365,7 @@ const jsonlOps: WalkOps = { } }, lookup(ast, key) { - const line = pickLine(ast, key); + const line = pickJsonlLine(ast, key); if (line === null) { return null; } @@ -440,37 +441,6 @@ function topLevelLeafText(value: JsoncValue, key: string): string | null { return null; } -function pickLine(ast: JsonlAst, addr: string): JsonlLine | null { - if (addr === "$first") { - for (const l of ast.lines) { - if (l.kind === "value") { - return l; - } - } - return null; - } - if (addr === "$last") { - for (let i = ast.lines.length - 1; i >= 0; i--) { - const l = ast.lines[i]; - if (l !== undefined && l.kind === "value") { - return l; - } - } - return null; - } - const m = /^L(\d+)$/.exec(addr); - if (m === null || m[1] === undefined) { - return null; - } - const target = Number(m[1]); - for (const l of ast.lines) { - if (l.line === target) { - return l; - } - } - return null; -} - // ---------- YAML walker ---------------------------------------------------- function walkYaml( diff --git a/extensions/oc-path/src/oc-path/jsonl/line.ts b/extensions/oc-path/src/oc-path/jsonl/line.ts new file mode 100644 index 00000000000..ec7ffaefd67 --- /dev/null +++ b/extensions/oc-path/src/oc-path/jsonl/line.ts @@ -0,0 +1,33 @@ +import { POS_FIRST, POS_LAST } from "../oc-path.js"; +import type { JsonlAst, JsonlLine } from "./ast.js"; + +export function pickJsonlLine(ast: JsonlAst, addr: string): JsonlLine | null { + if (addr === POS_FIRST) { + for (const line of ast.lines) { + if (line.kind === "value") { + return line; + } + } + return null; + } + if (addr === POS_LAST) { + for (let index = ast.lines.length - 1; index >= 0; index -= 1) { + const line = ast.lines[index]; + if (line !== undefined && line.kind === "value") { + return line; + } + } + return null; + } + const match = /^L(\d+)$/.exec(addr); + if (match === null || match[1] === undefined) { + return null; + } + const target = Number(match[1]); + for (const line of ast.lines) { + if (line.line === target) { + return line; + } + } + return null; +} diff --git a/extensions/oc-path/src/oc-path/jsonl/resolve.ts b/extensions/oc-path/src/oc-path/jsonl/resolve.ts index e77d4c50a75..65aef313777 100644 --- a/extensions/oc-path/src/oc-path/jsonl/resolve.ts +++ b/extensions/oc-path/src/oc-path/jsonl/resolve.ts @@ -18,14 +18,9 @@ import type { JsoncEntry, JsoncValue } from "../jsonc/ast.js"; import { resolveJsoncValueOcPath } from "../jsonc/resolve-value.js"; import type { OcPath } from "../oc-path.js"; -import { - POS_FIRST, - POS_LAST, - isQuotedSeg, - splitRespectingBrackets, - unquoteSeg, -} from "../oc-path.js"; +import { isQuotedSeg, splitRespectingBrackets, unquoteSeg } from "../oc-path.js"; import type { JsonlAst, JsonlLine } from "./ast.js"; +import { pickJsonlLine } from "./line.js"; export type JsonlOcPathMatch = | { readonly kind: "root"; readonly node: JsonlAst } @@ -50,7 +45,7 @@ export function resolveJsonlOcPath(ast: JsonlAst, path: OcPath): JsonlOcPathMatc return { kind: "root", node: ast }; } - const lineEntry = pickLine(ast, head); + const lineEntry = pickJsonlLine(ast, head); if (lineEntry === null) { return null; } @@ -90,34 +85,3 @@ export function resolveJsonlOcPath(ast: JsonlAst, path: OcPath): JsonlOcPathMatc } return { kind: "value", node: match.node, line: lineEntry.line, path: match.path }; } - -function pickLine(ast: JsonlAst, addr: string): JsonlLine | null { - if (addr === POS_FIRST) { - for (const l of ast.lines) { - if (l.kind === "value") { - return l; - } - } - return null; - } - if (addr === POS_LAST) { - for (let i = ast.lines.length - 1; i >= 0; i--) { - const l = ast.lines[i]; - if (l !== undefined && l.kind === "value") { - return l; - } - } - return null; - } - const m = /^L(\d+)$/.exec(addr); - if (m === null || m[1] === undefined) { - return null; - } - const target = Number(m[1]); - for (const l of ast.lines) { - if (l.line === target) { - return l; - } - } - return null; -}