From 0a37daf898652fe9af59ebafe65b5125a8975855 Mon Sep 17 00:00:00 2001 From: Martin Leduc <31558169+DecimalTurn@users.noreply.github.com> Date: Tue, 12 May 2026 11:11:52 -0400 Subject: [PATCH 1/4] refactor: change AST to CST --- README.md | 14 ++--- .../__snapshots__/ast-parsing.test.ts.snap | 8 +-- src/__tests__/ast-parsing.test.ts | 28 +++++----- src/__tests__/continue-parsing.test.ts | 4 +- src/__tests__/detect-trailing-comma.test.ts | 54 +++++++++---------- src/__tests__/find-by-path.test.ts | 12 ++--- src/__tests__/parse-js.test.ts | 6 +-- src/__tests__/patch.test.ts | 4 +- src/__tests__/roundtrip.patch-parse.test.ts | 4 +- src/__tests__/to-toml.test.ts | 2 +- src/__tests__/toml-document.test.ts | 48 ++++++++--------- src/__tests__/toml-format.test.ts | 18 +++---- src/__tests__/truncate.test.ts | 52 +++++++++--------- src/__tests__/validate-ast.test.ts | 26 ++++----- src/__tests__/writer.test.ts | 8 +-- src/ast.ts | 15 +++--- src/comment-alignment.ts | 6 +-- src/find-by-path.ts | 2 +- src/generate.ts | 2 +- src/index.ts | 2 +- src/parse-js.ts | 4 +- src/parse-toml.ts | 14 ++--- src/patch.ts | 25 +++++---- src/to-js.ts | 18 +++---- src/to-toml.ts | 18 +++---- src/toml-document.ts | 52 ++++++++++-------- src/toml-format.ts | 37 +++++++------ src/traverse.ts | 12 ++--- src/truncate.ts | 50 ++++++++++------- src/writer.ts | 12 ++--- 30 files changed, 295 insertions(+), 262 deletions(-) diff --git a/README.md b/README.md index c42bff8a..08bf4829 100644 --- a/README.md +++ b/README.md @@ -241,7 +241,7 @@ The `TomlDocument` class provides a stateful interface for working with TOML doc new TomlDocument(tomlSource: string | Uint8Array, options?: ParseOptions) ``` -Initializes the TomlDocument with TOML source, parsing it into an internal representation (AST). When bytes are provided they are decoded as UTF-8 in fatal mode, rejecting invalid sequences before parsing. +Initializes the TomlDocument with TOML source, parsing it into an internal representation (CST). When bytes are provided they are decoded as UTF-8 in fatal mode, rejecting invalid sequences before parsing. **Parameters:** - `tomlSource: string | Uint8Array` - The TOML source to parse @@ -289,22 +289,22 @@ overwrite(tomlString: string): void ``` **patch(updatedObject, format?)** -- Applies a patch to the current AST using a modified JS object -- Updates the internal AST while preserving formatting and comments +- Applies a patch to the current CST using a modified JS object +- Updates the internal CST while preserving formatting and comments - Use `toTomlString` getter to retrieve the updated TOML string - **Parameters:** - `updatedObject: any` - The modified JS object to patch with - `format?: Format` - Optional formatting options **update(tomlString)** -- Updates the internal AST by supplying a modified TOML string +- Updates the internal CST by supplying a modified TOML string - Uses incremental parsing for efficiency (only re-parses changed portions) - Use `toJsObject` getter to retrieve the updated JS object representation - **Parameters:** - `tomlString: string` - The modified TOML string to update with **overwrite(tomlString)** -- Overwrites the internal AST by fully re-parsing the supplied TOML string +- Overwrites the internal CST by fully re-parsing the supplied TOML string - Simpler but slower than `update()` which uses incremental parsing - **Parameters:** - `tomlString: string` - The TOML string to overwrite with @@ -425,7 +425,7 @@ const toml = stringify({ **newLine** - **Type:** `string` - **Default:** `'\n'` -- **Description:** The line ending character(s) to use in the output TOML. This option affects only the stringification process, not the internal representation (AST). +- **Description:** The line ending character(s) to use in the output TOML. This option affects only the stringification process, not the internal representation (CST). ```js const format = TomlFormat.default(); @@ -436,7 +436,7 @@ format.newLine = '\r\n'; // Windows line endings **trailingNewline** - **Type:** `number` - **Default:** `1` -- **Description:** The number of trailing newlines to add at the end of the TOML document. This option affects only the stringification process, not the internal representation (AST). +- **Description:** The number of trailing newlines to add at the end of the TOML document. This option affects only the stringification process, not the internal representation (CST). ```js const format = TomlFormat.default(); diff --git a/src/__tests__/__snapshots__/ast-parsing.test.ts.snap b/src/__tests__/__snapshots__/ast-parsing.test.ts.snap index 34329b62..4f71f607 100644 --- a/src/__tests__/__snapshots__/ast-parsing.test.ts.snap +++ b/src/__tests__/__snapshots__/ast-parsing.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`AST parsing comparison JS object to AST should parse nested objects with inline table formatting by default: js-object-ast 1`] = ` +exports[`CST parsing comparison JS object to CST should parse nested objects with inline table formatting by default: js-object-cst 1`] = ` Object { "items": Array [ Object { @@ -215,14 +215,14 @@ Object { } `; -exports[`AST parsing comparison JS object to AST should parse nested objects with inline table formatting by default: js-object-to-toml 1`] = ` +exports[`CST parsing comparison JS object to CST should parse nested objects with inline table formatting by default: js-object-to-toml 1`] = ` "[top] name = \\"example\\" nested = { key = \\"value\\" } " `; -exports[`AST parsing comparison TOML file to AST should parse nested tables preserving separate section formatting: toml-file-ast 1`] = ` +exports[`CST parsing comparison TOML file to CST should parse nested tables preserving separate section formatting: toml-file-cst 1`] = ` Object { "items": Array [ Object { @@ -423,7 +423,7 @@ Object { } `; -exports[`AST parsing comparison TOML file to AST should parse nested tables preserving separate section formatting: toml-file-to-toml 1`] = ` +exports[`CST parsing comparison TOML file to CST should parse nested tables preserving separate section formatting: toml-file-to-toml 1`] = ` "[top] name = \\"example\\" diff --git a/src/__tests__/ast-parsing.test.ts b/src/__tests__/ast-parsing.test.ts index c370524f..f57fa991 100644 --- a/src/__tests__/ast-parsing.test.ts +++ b/src/__tests__/ast-parsing.test.ts @@ -1,6 +1,6 @@ /** - * Tests for comparing AST structures when parsing from JS objects vs TOML files. - * This test explores the different ways the AST is built in both scenarios. + * Tests for comparing CST structures when parsing from JS objects vs TOML files. + * This test explores the different ways the CST is built in both scenarios. */ import parseJS from '../parse-js'; @@ -10,10 +10,10 @@ import { TomlFormat } from '../toml-format'; import { readFileSync } from 'fs'; import path from 'path'; -describe('AST parsing comparison', () => { +describe('CST parsing comparison', () => { const fmt = new TomlFormat(); - describe('JS object to AST', () => { + describe('JS object to CST', () => { it('should parse nested objects with inline table formatting by default', () => { const jsObject = { top: { @@ -24,12 +24,12 @@ describe('AST parsing comparison', () => { } }; - const ast = parseJS(jsObject); - const str = toTOML(ast.items, fmt); + const cst = parseJS(jsObject); + const str = toTOML(cst.items, fmt); // The default formatting for nested tables should be inline expect(str).toMatchSnapshot('js-object-to-toml'); - expect(ast).toMatchSnapshot('js-object-ast'); + expect(cst).toMatchSnapshot('js-object-cst'); // Verify that nested tables are formatted as inline by default expect(str).toContain('nested = { key = "value" }'); @@ -38,16 +38,16 @@ describe('AST parsing comparison', () => { }); }); - describe('TOML file to AST', () => { + describe('TOML file to CST', () => { it('should parse nested tables preserving separate section formatting', () => { const tomlInput = readFileSync( path.join(__dirname, '../__fixtures__/nested-tables.toml'), 'utf-8' ); - const astGenerator = parseTOML(tomlInput); - const blocks = Array.from(astGenerator); - const astFromToml = { + const cstGenerator = parseTOML(tomlInput); + const blocks = Array.from(cstGenerator); + const cstFromToml = { type: 'Document', items: blocks, loc: blocks.length > 0 ? { @@ -60,7 +60,7 @@ describe('AST parsing comparison', () => { // Should preserve the separate section formatting when parsed from TOML expect(strFromToml).toMatchSnapshot('toml-file-to-toml'); - expect(astFromToml).toMatchSnapshot('toml-file-ast'); + expect(cstFromToml).toMatchSnapshot('toml-file-cst'); // Verify that nested tables maintain separate sections expect(strFromToml).toContain('[top]'); @@ -85,8 +85,8 @@ describe('AST parsing comparison', () => { nested: { key: "value" } } }; - const jsAst = parseJS(jsObject); - const jsToml = toTOML(jsAst.items, fmt); + const jsCst = parseJS(jsObject); + const jsToml = toTOML(jsCst.items, fmt); // TOML file parsing preserves separate sections const tomlInput = readFileSync( diff --git a/src/__tests__/continue-parsing.test.ts b/src/__tests__/continue-parsing.test.ts index c3d71ca0..a4f027a1 100644 --- a/src/__tests__/continue-parsing.test.ts +++ b/src/__tests__/continue-parsing.test.ts @@ -3,7 +3,7 @@ import toJS from '../to-js'; import dedent from 'dedent'; describe('continueParsingTOML', () => { - it('appends parsed items from remaining string to existing AST', () => { + it('appends parsed items from remaining string to existing CST', () => { const initialToml = dedent` [section1] key1 = "value1" @@ -62,7 +62,7 @@ describe('continueParsingTOML', () => { }); }); - it('handles empty initial AST', () => { + it('handles empty initial CST', () => { const initialToml = ''; const remainingToml = dedent` [section] diff --git a/src/__tests__/detect-trailing-comma.test.ts b/src/__tests__/detect-trailing-comma.test.ts index 7b109826..f0ca50dc 100644 --- a/src/__tests__/detect-trailing-comma.test.ts +++ b/src/__tests__/detect-trailing-comma.test.ts @@ -3,32 +3,32 @@ import { TomlFormat } from '../toml-format'; import parseTOML from '../parse-toml'; function autoDetectFormat(toml: string) { - return TomlFormat.autoDetectFormatWithAst(toml, parseTOML(toml)); + return TomlFormat.autoDetectFormatWithCst(toml, parseTOML(toml)); } describe('detectTrailingComma', () => { test('should detect trailing comma in inline array', () => { const toml = `array = ["a", "b", "c",]`; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(true); }); test('should detect no trailing comma in inline array', () => { const toml = `array = ["a", "b", "c"]`; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(false); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(false); }); test('should detect trailing comma in inline table', () => { const toml = `table = { a = "1", b = "2", }`; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(true); }); test('should detect no trailing comma in inline table', () => { const toml = `table = { a = "1", b = "2" }`; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(false); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(false); }); test('should return false for TOML without comma-separated structures', () => { @@ -37,8 +37,8 @@ describe('detectTrailingComma', () => { [section] key = "value" `; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(false); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(false); }); test('should find trailing comma in nested structures', () => { @@ -47,8 +47,8 @@ describe('detectTrailingComma', () => { [section] array = ["a", "b",] `; - const ast = parseTOML(toml); - expect(detectTrailingComma(ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectTrailingComma(cst)).toBe(true); }); }); @@ -119,26 +119,26 @@ describe('TomlFormat.autoDetectFormat', () => { describe('detectBracketSpacing', () => { test('should detect bracket spacing in inline array', () => { const toml = `array = [ "a", "b", "c" ]`; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(true); }); test('should detect no bracket spacing in inline array', () => { const toml = `array = ["a", "b", "c"]`; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(false); + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(false); }); test('should detect bracket spacing in inline table', () => { const toml = `table = { a = "1", b = "2" }`; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(true); }); test('should detect no bracket spacing in inline table', () => { const toml = `table = {a = "1", b = "2"}`; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(false); + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(false); }); test('should return true for TOML without bracket structures', () => { @@ -147,8 +147,8 @@ describe('detectBracketSpacing', () => { [section] key = "value" `; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(true); // Default to true + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(true); // Default to true }); test('should find bracket spacing in nested structures', () => { @@ -157,16 +157,16 @@ describe('detectBracketSpacing', () => { [section] array = [ "a", "b" ] `; - const ast = parseTOML(toml); - expect(detectBracketSpacing(toml, ast)).toBe(true); + const cst = parseTOML(toml); + expect(detectBracketSpacing(toml, cst)).toBe(true); }); test('should handle mixed bracket spacing correctly', () => { const toml = `array1 = [ "a", "b" ] array2 = ["c", "d"]`; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Should return true based on the first occurrence found - expect(detectBracketSpacing(toml, ast)).toBe(true); + expect(detectBracketSpacing(toml, cst)).toBe(true); }); }); diff --git a/src/__tests__/find-by-path.test.ts b/src/__tests__/find-by-path.test.ts index f4f6413c..5b4ce035 100644 --- a/src/__tests__/find-by-path.test.ts +++ b/src/__tests__/find-by-path.test.ts @@ -5,11 +5,11 @@ import { Document, NodeType } from '../ast'; import dedent from 'dedent'; it('should find node by path', () => { - const ast = parseTOML(example); + const cst = parseTOML(example); const document: Document = { type: NodeType.Document, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }, - items: [...ast] + items: [...cst] }; expect(findByPath(document, []).type).toEqual('Document'); @@ -29,11 +29,11 @@ it('should find nodes within nested inline tables', () => { } `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); const document: Document = { type: NodeType.Document, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }, - items: [...ast] + items: [...cst] }; // Should find simple inline table properties @@ -84,11 +84,11 @@ it('should keep scanning AOT-scoped siblings after a shorter prefix match fails' name = "banana" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); const document: Document = { type: NodeType.Document, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }, - items: [...ast] + items: [...cst] }; const width = findByPath(document, ['fruit', 0, 'physical', 'dimensions', 'width']) as any; diff --git a/src/__tests__/parse-js.test.ts b/src/__tests__/parse-js.test.ts index 8b2e2f03..67f6b9a2 100644 --- a/src/__tests__/parse-js.test.ts +++ b/src/__tests__/parse-js.test.ts @@ -2,11 +2,11 @@ import parseJS from '../parse-js'; import parseTOML from '../parse-toml'; import toTOML from '../to-toml'; import dedent from 'dedent'; -import { NodeType, AST, Document } from '../ast'; +import { NodeType, CST, Document } from '../ast'; import { TomlFormat } from '../toml-format'; -function toDocument(ast: AST): Document { - const items = [...ast]; +function toDocument(cst: CST): Document { + const items = [...cst]; return { type: NodeType.Document, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }, diff --git a/src/__tests__/patch.test.ts b/src/__tests__/patch.test.ts index ea325923..e37c2af6 100644 --- a/src/__tests__/patch.test.ts +++ b/src/__tests__/patch.test.ts @@ -943,7 +943,7 @@ test('should patch example of modification of an inline-table element', () => { // of applyChanges (condition 3). // // Condition 3 fires when: -// - `existing` (from the original AST) is an InlineItem — i.e. a named key +// - `existing` (from the original CST) is an InlineItem — i.e. a named key // inside a root-level inline table such as `target = { type = "xlsm", path = "…" }` // - `replacement` (from parseJS on the updated object) is a bare KeyValue — because // `formatTopLevel` in parseJS promotes root-level objects to block [table] sections. @@ -2828,7 +2828,7 @@ test('should remove multiple leading KVs and preserve table section', () => { expect(patched).toContain('debug = true'); }); -// BUG: Same as validate-ast 'remove table array after leading KV' — +// BUG: Same as validate-CST 'remove table array after leading KV' — // findByPath fails for whole-table-array removal path ['tasks']. test('should remove table array and preserve leading KV', () => { const existing = dedent` diff --git a/src/__tests__/roundtrip.patch-parse.test.ts b/src/__tests__/roundtrip.patch-parse.test.ts index 89477e78..1372f207 100644 --- a/src/__tests__/roundtrip.patch-parse.test.ts +++ b/src/__tests__/roundtrip.patch-parse.test.ts @@ -13,7 +13,7 @@ function getTomlFiles(directoryPath: string): string[] { } /** - * Runs a roundtrip patch-parse AST test on a TOML file + * Runs a roundtrip patch-parse CST test on a TOML file * - Parses the original TOML into a TomlDocument * - Adds a new root key-value pair and patches the document * - Stringifies the patched document and parses it into a second TomlDocument @@ -34,7 +34,7 @@ function testRoundtripPatchParse(filePath: string) { const reparsedDoc = new TomlDocument(doc.toTomlString); // The two ASTs should be identical - expect(reparsedDoc.ast).toEqual(doc.ast); + expect(reparsedDoc.cst).toEqual(doc.cst); }); } diff --git a/src/__tests__/to-toml.test.ts b/src/__tests__/to-toml.test.ts index be692ea3..da0f94e4 100644 --- a/src/__tests__/to-toml.test.ts +++ b/src/__tests__/to-toml.test.ts @@ -4,7 +4,7 @@ import { example, kitchen_sink, hard_example, hard_example_unicode } from '../__ import dedent from 'dedent'; import { TomlFormat } from '../toml-format'; -test('it should convert ast to toml', () => { +test('it should convert CST to toml', () => { expect(toTOML(parseTOML(example), TomlFormat.default())).toEqual(example); }); diff --git a/src/__tests__/toml-document.test.ts b/src/__tests__/toml-document.test.ts index b3bc027d..9d6568d6 100644 --- a/src/__tests__/toml-document.test.ts +++ b/src/__tests__/toml-document.test.ts @@ -380,7 +380,7 @@ describe('TomlDocument', () => { expect(doc.toJsObject).toEqual({ section: { key: 'value' } }); }); - it('updates AST when a value changes', () => { + it('updates CST when a value changes', () => { const toml = dedent` [section] key = "value" @@ -602,7 +602,7 @@ describe('TomlDocument', () => { expect(doc.toJsObject).toEqual({ section: { key: 'value' } }); }); - it('overwrites AST when a value changes', () => { + it('overwrites CST when a value changes', () => { const toml = dedent` [section] key = "value" @@ -992,7 +992,7 @@ describe('TomlDocument', () => { }); }); - describe('update preserves unchanged AST nodes', () => { + describe('update preserves unchanged CST nodes', () => { it('preserves unchanged sections when updating a different section', () => { const toml = dedent` [section1] @@ -1005,7 +1005,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Update only section2 const updatedToml = dedent` @@ -1019,11 +1019,11 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; - // First section's AST node should be the same object reference + // First section's CST node should be the same object reference expect(updatedAst[0]).toBe(originalAst[0]); - // Second section's AST node should be different (was reparsed) + // Second section's CST node should be different (was reparsed) expect(updatedAst[1]).not.toBe(originalAst[1]); // Verify the values are correct @@ -1040,7 +1040,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Update only the third and fourth values const updatedToml = dedent` @@ -1051,9 +1051,9 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; - // First two AST nodes should be preserved + // First two CST nodes should be preserved expect(updatedAst[0]).toBe(originalAst[0]); expect(updatedAst[1]).toBe(originalAst[1]); // Last two should be different (reparsed) @@ -1067,7 +1067,7 @@ describe('TomlDocument', () => { expect(doc.toJsObject.fourth).toBe(100); }); - it('preserves entire AST when only a comment changes at the end', () => { + it('preserves entire CST when only a comment changes at the end', () => { const toml = dedent` # Comment at the start [section] @@ -1077,7 +1077,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Change only the comment at the end const updatedToml = dedent` @@ -1089,7 +1089,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // Original structure: [Comment, Table (containing a comment inside)] // After update: [Comment (unchanged), Table (changed because comment inside changed)] @@ -1104,7 +1104,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Add a new section after the first one const updatedToml = dedent` @@ -1116,7 +1116,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // First section should be preserved expect(updatedAst[0]).toBe(originalAst[0]); @@ -1140,7 +1140,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Update only the third product const updatedToml = dedent` @@ -1158,7 +1158,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // First two array table elements should be preserved expect(updatedAst[0]).toBe(originalAst[0]); @@ -1183,7 +1183,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; const originalLength = originalAst.length; // Add a new section at the end @@ -1199,7 +1199,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // All original nodes should be preserved for (let i = 0; i < originalLength; i++) { @@ -1233,7 +1233,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Update only servers.beta const updatedToml = dedent` @@ -1253,7 +1253,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.update(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // Title, database, and servers.alpha should be preserved expect(updatedAst[0]).toBe(originalAst[0]); // title @@ -1270,7 +1270,7 @@ describe('TomlDocument', () => { expect(doc.toJsObject.servers.beta.ip).toBe('10.0.0.99'); }); - it('overwrite does NOT preserve AST nodes (for comparison)', () => { + it('overwrite does NOT preserve CST nodes (for comparison)', () => { const toml = dedent` [section1] key1 = "value1" @@ -1280,7 +1280,7 @@ describe('TomlDocument', () => { ` + '\n'; const doc = new TomlDocument(toml); - const originalAst = doc.ast; + const originalAst = doc.cst; // Use overwrite instead of update const updatedToml = dedent` @@ -1292,7 +1292,7 @@ describe('TomlDocument', () => { ` + '\n'; doc.overwrite(updatedToml); - const updatedAst = doc.ast; + const updatedAst = doc.cst; // With overwrite, ALL nodes are reparsed, so none should be preserved expect(updatedAst[0]).not.toBe(originalAst[0]); diff --git a/src/__tests__/toml-format.test.ts b/src/__tests__/toml-format.test.ts index ad5cc004..9b2a0577 100644 --- a/src/__tests__/toml-format.test.ts +++ b/src/__tests__/toml-format.test.ts @@ -5,7 +5,7 @@ import toTOML from '../to-toml'; import { stripLeadingBom } from '../decode-utf8'; function autoDetectFormat(toml: string) { - return TomlFormat.autoDetectFormatWithAst(toml, parseTOML(stripLeadingBom(toml))); + return TomlFormat.autoDetectFormatWithCst(toml, parseTOML(stripLeadingBom(toml))); } describe('TomlFormat comprehensive tests', () => { @@ -343,8 +343,8 @@ describe('TomlFormat comprehensive tests', () => { test('should preserve CRLF in autoDetectFormat roundtrip', () => { const original = 'key = "value"\r\n[section]\r\ndata = "test"\r\n\r\n'; const format = autoDetectFormat(original); - const ast = parseTOML(original); - const result = toTOML(ast, format); + const cst = parseTOML(original); + const result = toTOML(cst, format); expect(format.newLine).toBe('\r\n'); expect(format.trailingNewline).toBe(2); @@ -354,8 +354,8 @@ describe('TomlFormat comprehensive tests', () => { test('should preserve trailing comma preference in autoDetectFormat roundtrip', () => { const original = 'arr = ["a", "b", ]\ntable = ["x", "y", ]\n'; const format = autoDetectFormat(original); - const ast = parseTOML(original); - const result = toTOML(ast, format); + const cst = parseTOML(original); + const result = toTOML(cst, format); expect(format.trailingComma).toBe(true); expect(result).toBe(original); @@ -371,8 +371,8 @@ describe('TomlFormat comprehensive tests', () => { test('should preserve no trailing newlines in autoDetectFormat roundtrip', () => { const original = 'key = "value"'; const format = autoDetectFormat(original); - const ast = parseTOML(original); - const result = toTOML(ast, format); + const cst = parseTOML(original); + const result = toTOML(cst, format); expect(format.trailingNewline).toBe(0); expect(result).toBe(original); @@ -449,8 +449,8 @@ data = "test"`; test('should reuse an existing parse tree when auto-detecting format', () => { const toml = 'title = "Cached"\narray = ["a", "b", ]\n'; - const ast = Array.from(parseTOML(toml)); - const format = TomlFormat.autoDetectFormatWithAst(toml, ast); + const cst = Array.from(parseTOML(toml)); + const format = TomlFormat.autoDetectFormatWithCst(toml, cst); expect(format.newLine).toBe('\n'); expect(format.trailingNewline).toBe(1); diff --git a/src/__tests__/truncate.test.ts b/src/__tests__/truncate.test.ts index 99aa46a7..60a203a4 100644 --- a/src/__tests__/truncate.test.ts +++ b/src/__tests__/truncate.test.ts @@ -1,11 +1,11 @@ import parseTOML from '../parse-toml'; -import { truncateAst, findLastNodeBeforePosition } from '../truncate'; +import { truncateCst, findLastNodeBeforePosition } from '../truncate'; import toJS from '../to-js'; import { NodeType } from '../ast'; import dedent from 'dedent'; describe('truncateAst', () => { - it('truncates AST at specified position', () => { + it('truncates CST at specified position', () => { const toml = dedent` [section1] key1 = "value1" @@ -14,9 +14,9 @@ describe('truncateAst', () => { key2 = "value2" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate at line 3 (before section2) - const { truncatedAst, lastEndPosition } = truncateAst(ast, 3, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 3, 0); const result = toJS(truncatedAst); expect(result).toEqual({ @@ -34,9 +34,9 @@ describe('truncateAst', () => { key2 = "value2" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate at a position beyond the document - const { truncatedAst, lastEndPosition } = truncateAst(ast, 100, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 100, 0); const result = toJS(truncatedAst); expect(result).toEqual({ @@ -46,15 +46,15 @@ describe('truncateAst', () => { expect(lastEndPosition).not.toBeNull(); }); - it('returns empty AST when position is before any content', () => { + it('returns empty CST when position is before any content', () => { const toml = dedent` [section1] key1 = "value1" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate at line 0 (before everything) - const { truncatedAst, lastEndPosition } = truncateAst(ast, 0, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 0, 0); const result = toJS(truncatedAst); expect(result).toEqual({}); @@ -72,10 +72,10 @@ describe('truncateAst', () => { key2 = "value2" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate just before section2 (line 6 starts section2, so use line 5) - const { truncatedAst, lastEndPosition } = truncateAst(ast, 5, 999); - const truncated = [...truncatedAst]; + const { truncatedCst, lastEndPosition } = truncateCst(cst, 5, 999); + const truncated = [...truncatedCst]; // Should include: Comment 1, section1 (with key1 and Comment 2 inside its items) expect(truncated).toHaveLength(2); // Comment, Table @@ -91,11 +91,11 @@ describe('truncateAst', () => { c = 3 `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate at line 2, column 0 (right at the start of "b = 2") // With the new semantics, this should only include blocks that END before line 2, column 0 // So only "a = 1" which ends at line 1 - const { truncatedAst, lastEndPosition } = truncateAst(ast, 2, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 2, 0); const result = toJS(truncatedAst); expect(result).toEqual({ a: 1 }); @@ -114,9 +114,9 @@ describe('truncateAst', () => { name = "Product 3" `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate to include only first two products - const { truncatedAst, lastEndPosition } = truncateAst(ast, 6, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 6, 0); const result = toJS(truncatedAst); expect(result).toEqual({ @@ -140,11 +140,11 @@ describe('truncateAst', () => { key3 = 3 `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Truncate at line 5, column 0 (start of [parent.child2]) // With the new semantics, this should only include blocks that END before line 5 // So only [parent.child1] which ends at line 2 - const { truncatedAst, lastEndPosition } = truncateAst(ast, 5, 0); + const { truncatedCst, lastEndPosition } = truncateCst(cst, 5, 0); const result = toJS(truncatedAst); expect(result).toEqual({ @@ -166,8 +166,8 @@ describe('findLastNodeBeforePosition', () => { key2 = "value2" `; - const ast = parseTOML(toml); - const lastNode = findLastNodeBeforePosition(ast, 3, 0); + const cst = parseTOML(toml); + const lastNode = findLastNodeBeforePosition(cst, 3, 0); expect(lastNode).toBeDefined(); expect(lastNode?.type).toBe(NodeType.Table); @@ -179,8 +179,8 @@ describe('findLastNodeBeforePosition', () => { key1 = "value1" `; - const ast = parseTOML(toml); - const lastNode = findLastNodeBeforePosition(ast, 0, 0); + const cst = parseTOML(toml); + const lastNode = findLastNodeBeforePosition(cst, 0, 0); expect(lastNode).toBeUndefined(); }); @@ -194,8 +194,8 @@ describe('findLastNodeBeforePosition', () => { key2 = "value2" `; - const ast = parseTOML(toml); - const lastNode = findLastNodeBeforePosition(ast, 100, 0); + const cst = parseTOML(toml); + const lastNode = findLastNodeBeforePosition(cst, 100, 0); expect(lastNode).toBeDefined(); expect(lastNode?.type).toBe(NodeType.Table); @@ -227,9 +227,9 @@ describe('findLastNodeBeforePosition', () => { c = 3 `; - const ast = parseTOML(toml); + const cst = parseTOML(toml); // Position at the start of "b = 2" - const lastNode = findLastNodeBeforePosition(ast, 2, 0); + const lastNode = findLastNodeBeforePosition(cst, 2, 0); expect(lastNode).toBeDefined(); expect(lastNode?.type).toBe(NodeType.KeyValue); diff --git a/src/__tests__/validate-ast.test.ts b/src/__tests__/validate-ast.test.ts index 38ce0912..2421e2db 100644 --- a/src/__tests__/validate-ast.test.ts +++ b/src/__tests__/validate-ast.test.ts @@ -4,7 +4,7 @@ import { } from '../ast'; import { Location, Position } from '../location'; import parseTOML from '../parse-toml'; -import { patchAst } from '../patch'; +import { patchCst } from '../patch'; import { TomlFormat } from '../toml-format'; import traverse from '../traverse'; import dedent from 'dedent'; @@ -38,8 +38,8 @@ function locStr(loc: Location): string { /** * Check whether `child`'s location is fully contained within `parent`'s location. * - * @param parent - The enclosing AST node. - * @param child - The nested AST node whose location is being validated. + * @param parent - The enclosing CST node. + * @param child - The nested CST node whose location is being validated. * @returns A human-readable error string describing the violation, or `null` when * the child is properly contained. */ @@ -66,7 +66,7 @@ function checkContainment( } /** - * Walk the AST and return an array of human-readable overlap descriptions. + * Walk the CST and return an array of human-readable overlap descriptions. * An empty array means all child positions fit within their parents. * * Validates every parent→child edge in the tree, including: @@ -170,27 +170,27 @@ function findInvertedLocations(doc: Document): string[] { /** * Parse `toml`, apply `updated` as a patch, and return any parent-child - * location-overlap violations found in the resulting AST. + * location-overlap violations found in the resulting CST. * * @param toml - TOML source string to parse and patch. * @param updated - Plain JS object representing the desired document state. * @returns Overlap violation strings from {@link findPositionOverlaps}. */ function getOverlaps(toml: string, updated: any): string[] { - const { document } = patchAst(parseTOML(toml), updated, new TomlFormat()); + const { document } = patchCst(parseTOML(toml), updated, new TomlFormat()); return findPositionOverlaps(document); } /** * Parse `toml`, apply `updated` as a patch, and return any inverted-location - * violations found in the resulting AST. + * violations found in the resulting CST. * * @param toml - TOML source string to parse and patch. * @param updated - Plain JS object representing the desired document state. * @returns Inverted-location violation strings from {@link findInvertedLocations}. */ function getInverted(toml: string, updated: any): string[] { - const { document } = patchAst(parseTOML(toml), updated, new TomlFormat()); + const { document } = patchCst(parseTOML(toml), updated, new TomlFormat()); return findInvertedLocations(document); } @@ -212,16 +212,16 @@ function expectConsistent(toml: string, updated: any) { // --------------------------------------------------------------------------- /** - * These tests check whether the AST returned by patchAst() has consistent + * These tests check whether the CST returned by patchAst() has consistent * position metadata after modifications (no parent-child location overlaps). * - * The TOML string output is always correct — toTOML serializes from the AST - * structure, not from raw positions. However, the AST position metadata may + * The TOML string output is always correct — toTOML serializes from the CST + * structure, not from raw positions. However, the CST position metadata may * become inconsistent when the writer adjusts nodes without fully propagating * position changes to parent containers. */ -describe('AST position consistency after patching', () => { +describe('CST position consistency after patching', () => { // ------ inline array mutations ------ @@ -274,7 +274,7 @@ describe('AST position consistency after patching', () => { test('Document end position contracts after key removal', () => { // Removing `b = 2` from a two-key document should shrink the document end // to the last remaining line (line 1 / `a = 1`). - const { document } = patchAst(parseTOML('a = 1\nb = 2\n'), { a: 1 }, new TomlFormat()); + const { document } = patchCst(parseTOML('a = 1\nb = 2\n'), { a: 1 }, new TomlFormat()); expect(document.loc.end.line).toBe(1); expect(document.loc.end.column).toBe(5); expectConsistent('a = 1\nb = 2\n', { a: 1 }); diff --git a/src/__tests__/writer.test.ts b/src/__tests__/writer.test.ts index ae9fdcb1..10d5ff0e 100644 --- a/src/__tests__/writer.test.ts +++ b/src/__tests__/writer.test.ts @@ -13,22 +13,22 @@ import { String as StringNode, NodeType } from '../ast'; test('it should insert elements into empty inline array', () => { const inline_array = generateInlineArray(); const key_value = generateKeyValue(['a'], inline_array); - const ast = [key_value]; + const cst = [key_value]; const format = TomlFormat.default(); - expect(toTOML(ast, format)).toEqual(`a = []\n`); + expect(toTOML(cst, format)).toEqual(`a = []\n`); insert(key_value, inline_array, generateInlineItem(generateString('b'))); applyWrites(key_value); - expect(toTOML(ast, format)).toEqual(`a = ["b"]\n`); + expect(toTOML(cst, format)).toEqual(`a = ["b"]\n`); insert(key_value, inline_array, generateInlineItem(generateString('c'))); insert(key_value, inline_array, generateInlineItem(generateString('d'))); insert(key_value, inline_array, generateInlineItem(generateString('e'))); applyWrites(key_value); - expect(toTOML(ast, format)).toEqual(`a = ["b", "c", "d", "e"]\n`); + expect(toTOML(cst, format)).toEqual(`a = ["b", "c", "d", "e"]\n`); }); test('it should insert first item on first line in document', () => { diff --git a/src/ast.ts b/src/ast.ts index 102ce945..ef8eb92c 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -28,16 +28,19 @@ export enum NodeType { } // -// Abstract Syntax Tree +// Concrete Syntax Tree // -// AST nodes are used to represent TOML data +// CST nodes are used to represent TOML data // -export type AST = Iterable; +export type CST = Iterable; + +/** @deprecated Use CST instead. */ +export type AST = CST; // // Document // -// Top-level document that stores AST nodes +// Top-level document that stores CST nodes // export interface Document extends TreeNode { type: NodeType.Document; @@ -250,7 +253,7 @@ export function isInlineArray(node: TreeNode): node is InlineArray { return node.type === NodeType.InlineArray; } -// InlineItem (internal AST wrapper — not a TOML spec concept) +// InlineItem (internal CST wrapper — not a TOML spec concept) // // InlineItem is a container node that wraps each element inside an inline // container (InlineArray or InlineTable). It carries two responsibilities: @@ -419,7 +422,7 @@ export function hasItem(node: TreeNode): node is WithItem { * ``` * * Type Safety: - * This distinction is crucial for the AST structure because: + * This distinction is crucial for the CST structure because: * - Document.items: Block[] * - Table.items: RowItem[] (KeyValue | Comment) * - TableArray.items: RowItem[] (KeyValue | Comment) diff --git a/src/comment-alignment.ts b/src/comment-alignment.ts index 8a970933..8fc5491f 100644 --- a/src/comment-alignment.ts +++ b/src/comment-alignment.ts @@ -102,7 +102,7 @@ function applyInlineCommentColumnAdjustment(comment: Comment, targetColumn: numb /** * Stores the current minimum spacing between a row and its trailing comment. * - * This data is refreshed each time it is observed so reused AST comment nodes + * This data is refreshed each time it is observed so reused CST comment nodes * do not retain stale spacing or column values from a previous patch run. * * @param row Key-value row that owns the trailing comment. @@ -270,7 +270,7 @@ export function recordInlineTableCommentDelta(container: TreeNode, row: KeyValue * needed by the surrounding inline array or inline table formatting. * * @param parent Inline container receiving the new child. - * @param child AST node being inserted. + * @param child CST node being inserted. * @param index Target insertion index. * @returns The number of columns added to the rendered row. */ @@ -388,7 +388,7 @@ function recomputeContainerEnds(node: Document | Table | TableArray) { * For groups touched by nested inline-table edits, the target column is derived * from the widest current row plus the group's original minimum reserved gap. * - * @param document Patched AST document whose comment locations are updated in-place. + * @param document Patched CST document whose comment locations are updated in-place. * @param tomlString Rendered TOML output to normalize. * @param format Active TOML formatting settings. * @returns The normalized TOML string. diff --git a/src/find-by-path.ts b/src/find-by-path.ts index 103732f2..b0251f9e 100644 --- a/src/find-by-path.ts +++ b/src/find-by-path.ts @@ -103,7 +103,7 @@ export default function findByPath(node: TreeNode, path: Path): TreeNode { /** * Searches for a path within an AOT entry's logical scope. * - * In the TOML AST, sub-tables and sub-AOTs under a [[name]] entry are stored + * In the TOML CST, sub-tables and sub-AOTs under a [[name]] entry are stored * as siblings in the Document rather than as children of the entry node. * This function first tries the entry's own items, then falls back to the * scoped document items (those between this [[name]] and the next [[name]]). diff --git a/src/generate.ts b/src/generate.ts index 4fbee1aa..889c1663 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,5 +1,5 @@ /** - * @file Helpers to generate and update TOML AST nodes. + * @file Helpers to generate and update TOML CST nodes. * @module generate */ diff --git a/src/index.ts b/src/index.ts index 8838830d..9ada85f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,6 +86,6 @@ export { LocalDate, LocalTime, LocalDateTime, OffsetDateTime } from './parse-tom export { TomlFormat } from './toml-format'; /** - * TomlDocument encapsulates a TOML AST and provides methods to interact with it. + * TomlDocument encapsulates a TOML CST and provides methods to interact with it. */ export { TomlDocument } from './toml-document'; diff --git a/src/parse-js.ts b/src/parse-js.ts index fb1e2189..a312ddff 100644 --- a/src/parse-js.ts +++ b/src/parse-js.ts @@ -17,10 +17,10 @@ import { isObject, isString, isBigInt, isInteger, isFloat, isBoolean, isDate } f import { insert, applyWrites, applyBracketSpacing, applyTrailingComma } from './writer'; /** - * Parses a JavaScript object into an AST Document, applying formatting options from TomlFormat. + * Parses a JavaScript object into a CST Document, applying formatting options from TomlFormat. * @param value - The JavaScript object to parse. * @param format - The formatting options to apply. - * @returns The resulting AST Document. + * @returns The resulting CST Document. */ export default function parseJS(value: any, format: TomlFormat = TomlFormat.default()): Document { value = toJSON(value); diff --git a/src/parse-toml.ts b/src/parse-toml.ts index 2330f689..71c044d4 100644 --- a/src/parse-toml.ts +++ b/src/parse-toml.ts @@ -15,7 +15,7 @@ import { InlineTable, InlineArray, Comment, - AST, + CST, Block } from './ast'; import { Token, TokenType, tokenize, DOUBLE_QUOTE, SINGLE_QUOTE } from './tokenizer'; @@ -250,7 +250,7 @@ export { DateFormatHelper } from './date-format'; -export default function* parseTOML(input: string): AST { +export default function* parseTOML(input: string): CST { // Use non-generator parsing to avoid stack overflow on deeply nested structures const cursor = new Cursor(tokenize(input)); @@ -263,14 +263,14 @@ export default function* parseTOML(input: string): AST { } /** - * Continues parsing TOML from a remaining string and appends the results to an existing AST. + * Continues parsing TOML from a remaining string and appends the results to an existing CST. * - * @param existingAst - The existing AST to append to + * @param existingAst - The existing CST to append to * @param remainingString - The remaining TOML string to parse - * @returns A new complete AST with both the existing and newly parsed items + * @returns A new complete CST with both the existing and newly parsed items */ -export function* continueParsingTOML(existingAst: AST, remainingString: string): AST { - // Yield all items from the existing AST +export function* continueParsingTOML(existingAst: CST, remainingString: string): CST { + // Yield all items from the existing CST for (const item of existingAst) { yield item; } diff --git a/src/patch.ts b/src/patch.ts index 94a5ca52..24bd5fee 100644 --- a/src/patch.ts +++ b/src/patch.ts @@ -21,7 +21,7 @@ import { hasItem, hasItems, InlineItem, - AST, + CST, Table, Value, isDateTime @@ -60,18 +60,18 @@ import { stripLeadingBom, UTF8_BOM } from './decode-utf8'; * @returns A new TOML string with the changes applied */ export default function patch(existing: string, updated: any, format?: Partial | TomlFormat): string { - const existing_ast = Array.from(parseTOML(stripLeadingBom(existing))); + const existing_cst = Array.from(parseTOML(stripLeadingBom(existing))); // Auto-detect formatting preferences from the existing TOML string for fallback - const autoDetectedFormat = TomlFormat.autoDetectFormatWithAst(existing, existing_ast); + const autoDetectedFormat = TomlFormat.autoDetectFormatWithCst(existing, existing_cst); const fmt = resolveTomlFormat(format, autoDetectedFormat); - const patchedToml = patchAst(existing_ast, updated, fmt).tomlString; + const patchedToml = patchCst(existing_cst, updated, fmt).tomlString; return fmt.leadingBom ? `${UTF8_BOM}${patchedToml}` : patchedToml; } -export function patchAst(existing_ast:AST, updated: any, format: TomlFormat): { tomlString: string; document: Document } { - const items = [...existing_ast]; +export function patchCst(existing_cst: CST, updated: any, format: TomlFormat): { tomlString: string; document: Document } { + const items = [...existing_cst]; // Compute the Document's end position from its children so that // offset-based position updates in applyWrites start from the correct @@ -126,6 +126,9 @@ export function patchAst(existing_ast:AST, updated: any, format: TomlFormat): { }; } +/** @deprecated Use patchCst instead. */ +export const patchAst = patchCst; + function reorder(changes: Change[]): Change[] { //Reorder deletions among themselves to avoid index issues // We want the path to be looking at the last item in the array first and go down from there @@ -211,15 +214,15 @@ function preserveFormatting(existing: Value, replacement: Value): void { } /** - * Applies a list of changes to the original TOML document AST while preserving formatting and structure. + * Applies a list of changes to the original TOML document CST while preserving formatting and structure. * * This function processes different types of changes (Add, Edit, Remove, Move, Rename) and applies them * to the original document in a way that maintains the existing formatting preferences, comments, and * structural elements as much as possible. Special handling is provided for different node types like * inline tables, arrays, and table arrays to ensure proper formatting consistency. * - * @param original - The original TOML document AST to be modified - * @param updated - The updated document AST containing new values for changes + * @param original - The original TOML document CST to be modified + * @param updated - The updated document CST containing new values for changes * @param changes - Array of change objects describing what modifications to apply * @param format - Formatting preferences to use for newly added elements * @returns The modified original document with all changes applied @@ -507,7 +510,7 @@ function applyChanges(original: Document, updated: Document, changes: Change[], if (!node) { // The path likely refers to all entries of a TableArray sequence - // (e.g. path ['tasks'] when the AST stores entries at ['tasks',0], ['tasks',1]…). + // (e.g. path ['tasks'] when the CST stores entries at ['tasks',0], ['tasks',1]…). // Remove all entries by repeatedly pulling the one at index 0. const first = tryFindByPath(original, change.path.concat(0)); if (first) { @@ -535,7 +538,7 @@ function applyChanges(original: Document, updated: Document, changes: Change[], if (isInlineItem(parent) && isInlineTable((parent as InlineItem).item)) { parent = (parent as InlineItem).item; } - // The logical (JS-object) parent may differ from the AST parent. + // The logical (JS-object) parent may differ from the CST parent. // For example, [server.tls] lives in document.items, not [server].items. // Fall back to the document root when the parent doesn't contain the node. if (hasItems(parent) && !(parent.items as TreeNode[]).includes(node)) { diff --git a/src/to-js.ts b/src/to-js.ts index bd69be7e..287f5ccd 100644 --- a/src/to-js.ts +++ b/src/to-js.ts @@ -1,4 +1,4 @@ -import { Value, NodeType, TreeNode, AST, InlineTable, Table, TableArray, KeyValue } from './ast'; +import { Value, NodeType, TreeNode, CST, InlineTable, Table, TableArray, KeyValue } from './ast'; import { last, blank, isDate, has } from './utils'; import ParseError from './parse-error'; import { IntegersAsBigInt } from './parse-options'; @@ -55,13 +55,13 @@ function trackNestedInlineTables(inlineTable: InlineTable, basePath: string[], i } /** - * Converts the given AST to a JavaScript object. + * Converts the given CST to a JavaScript object. * - * @param ast The abstract syntax tree to convert. + * @param cst The Concrete Syntax Tree to convert. * @param input The original input string (used for error reporting). - * @returns The JavaScript object representation of the AST. + * @returns The JavaScript object representation of the CST. */ -export default function toJS(ast: AST, input: string = '', integersAsBigInt: IntegersAsBigInt = 'asNeeded'): any { +export default function toJS(cst: CST, input: string = '', integersAsBigInt: IntegersAsBigInt = 'asNeeded'): any { const result = blank(); const tables: Set = new Set(); const table_arrays: Set = new Set(); @@ -76,8 +76,8 @@ export default function toJS(ast: AST, input: string = '', integersAsBigInt: Int // Specialized inline walk — only visits Table, TableArray, and KeyValue. // Skips Comment, Key, Value sub-nodes entirely (toValue handles InlineTable/ // InlineArray recursively). This avoids the overhead of the generic traverse - // dispatching through every AST node. - for (const block of ast) { + // dispatching through every CST node. + for (const block of cst) { switch (block.type) { case NodeType.Table: handleTable(block as Table); @@ -178,8 +178,8 @@ export default function toJS(ast: AST, input: string = '', integersAsBigInt: Int } /** - * Converts a TOML AST value node to a JavaScript value. - * @param node The TOML AST value node. + * Converts a TOML CST value node to a JavaScript value. + * @param node The TOML CST value node. * @returns The corresponding JavaScript value. */ export function toValue(node: Value, integersAsBigInt: IntegersAsBigInt = 'asNeeded'): any { diff --git a/src/to-toml.ts b/src/to-toml.ts index eb33adc7..1f0460f0 100644 --- a/src/to-toml.ts +++ b/src/to-toml.ts @@ -1,6 +1,6 @@ import { NodeType, - AST, + CST, TreeNode, Document, Table, @@ -27,22 +27,22 @@ import { isIterable } from './utils'; const BY_NEW_LINE = /(\r\n|\n)/g; /** - * Converts an Abstract Syntax Tree (AST) back to TOML format string. + * Converts a Concrete Syntax Tree (CST) back to TOML format string. * - * This function traverses the AST and reconstructs the original TOML document + * This function traverses the CST and reconstructs the original TOML document * by writing each node's raw content to the appropriate location coordinates. * It preserves the original formatting, spacing, and structure of the TOML file. * - * @param ast - The Abstract Syntax Tree representing the parsed TOML document + * @param cst - The Concrete Syntax Tree representing the parsed TOML document * @param format - The formatting options to use for the output * @returns The reconstructed TOML document as a string * * @example * ```typescript - * const tomlString = toTOML(ast, TomlFormat.default()); + * const tomlString = toTOML(cst, TomlFormat.default()); * ``` */ -export default function toTOML(ast: AST, format: TomlFormat): string { +export default function toTOML(cst: CST, format: TomlFormat): string { const lines: string[] = []; @@ -153,10 +153,10 @@ export default function toTOML(ast: AST, format: TomlFormat): string { } // Handle both Document nodes and bare iterables (document.items) - if (isIterable(ast)) { - for (const item of ast) emitNode(item as TreeNode); + if (isIterable(cst)) { + for (const item of cst) emitNode(item as TreeNode); } else { - emitNode(ast as unknown as TreeNode); + emitNode(cst as unknown as TreeNode); } // Post-process: convert leading spaces to tabs if useTabsForIndentation is enabled diff --git a/src/toml-document.ts b/src/toml-document.ts index f77ca0b6..d6a10948 100644 --- a/src/toml-document.ts +++ b/src/toml-document.ts @@ -2,23 +2,23 @@ import parseTOML, { continueParsingTOML } from './parse-toml'; import toJS from './to-js'; import { TomlFormat } from './toml-format'; import { Block } from './ast'; -import { patchAst } from './patch'; +import { patchCst } from './patch'; import { detectNewline, resolveTomlFormat } from './toml-format'; -import { truncateAst } from './truncate'; +import { truncateCst } from './truncate'; import type { ParseOptions, IntegersAsBigInt } from './parse-options'; import { decodeUtf8Bytes, hasLeadingBom, stripLeadingBom, UTF8_BOM } from './decode-utf8'; /** - * TomlDocument encapsulates a TOML AST and provides methods to interact with it. + * TomlDocument encapsulates a TOML CST and provides methods to interact with it. */ export class TomlDocument { - private _ast: Block[]; + private _cst: Block[]; private _currentTomlString: string; private _format: TomlFormat; private _integersAsBigInt: IntegersAsBigInt; /** - * Initializes the TomlDocument with TOML source, parsing it into an AST. + * Initializes the TomlDocument with TOML source, parsing it into a CST. * * When bytes are provided, they are decoded as UTF-8 in fatal mode. * This rejects invalid UTF-8 sequences before parsing. @@ -34,10 +34,10 @@ export class TomlDocument { const tomlString = stripLeadingBom(sourceString); this._currentTomlString = tomlString; - this._ast = Array.from(parseTOML(tomlString)); + this._cst = Array.from(parseTOML(tomlString)); this._integersAsBigInt = options?.integersAsBigInt ?? 'asNeeded'; // Auto-detect formatting preferences from the original TOML string - this._format = TomlFormat.autoDetectFormatWithAst(sourceString, this._ast); + this._format = TomlFormat.autoDetectFormatWithCst(sourceString, this._cst); } get toTomlString(): string { @@ -48,22 +48,32 @@ export class TomlDocument { * Returns the JavaScript object representation of the TOML document. */ get toJsObject(): any { - const jsObject = toJS(this._ast, this._currentTomlString, this._integersAsBigInt); + const jsObject = toJS(this._cst, this._currentTomlString, this._integersAsBigInt); // Convert custom date classes to regular JavaScript Date objects return convertCustomDateClasses(jsObject); } /** - * Returns the internal AST (for testing purposes). + * Returns the internal CST (for testing purposes). * @internal */ + get cst(): Block[] { + return this._cst; + } + + /** @deprecated Use cst instead. */ + get CST(): Block[] { + return this._cst; + } + + /** @deprecated Use cst instead. */ get ast(): Block[] { - return this._ast; + return this._cst; } /** - * Applies a patch to the current AST using a modified JS object. - * Updates the internal AST. Use toTomlString getter to retrieve the updated TOML string. + * Applies a patch to the current CST using a modified JS object. + * Updates the internal CST. Use toTomlString getter to retrieve the updated TOML string. * @param updatedObject - The modified JS object to patch with * @param format - Optional formatting options */ @@ -71,12 +81,12 @@ export class TomlDocument { const fmt = resolveTomlFormat(format, this._format); - const { tomlString, document } = patchAst( - this._ast, + const { tomlString, document } = patchCst( + this._cst, updatedObject, fmt ); - this._ast = document.items; + this._cst = document.items; this._format = fmt; this._currentTomlString = tomlString; } @@ -126,7 +136,7 @@ export class TomlDocument { } let firstDiffLine = firstDiffLineIndex + 1; // Convert to 1-based - const { truncatedAst, lastEndPosition } = truncateAst(this._ast, firstDiffLine, firstDiffColumn); + const { truncatedCst, lastEndPosition } = truncateCst(this._cst, firstDiffLine, firstDiffColumn); // Determine where to continue parsing from in the new string // If lastEndPosition exists, continue from there; otherwise from the start of the document @@ -134,7 +144,7 @@ export class TomlDocument { const continueFromColumn = lastEndPosition ? lastEndPosition.column + 1 : 0; // Based on the first difference, we can re-parse only the affected part - // We will need to supply the remaining string after where the AST was truncated + // We will need to supply the remaining string after where the CST was truncated const remainingLines = newTextLines.slice(continueFromLine - 1); // If there's a partial line match, we need to extract only the part after the continuation column @@ -144,11 +154,11 @@ export class TomlDocument { const remainingToml = remainingLines.join(this._format.newLine); - this._ast = Array.from(continueParsingTOML(truncatedAst, remainingToml)); + this._cst = Array.from(continueParsingTOML(truncatedCst, remainingToml)); this._currentTomlString = tomlContent; // Update the auto-detected format with the new string's characteristics - this._format = TomlFormat.autoDetectFormatWithAst(tomlString, this._ast); + this._format = TomlFormat.autoDetectFormatWithCst(tomlString, this._cst); } /** @@ -165,11 +175,11 @@ export class TomlDocument { } // Re-parse the entire document - this._ast = Array.from(parseTOML(tomlContent)); + this._cst = Array.from(parseTOML(tomlContent)); this._currentTomlString = tomlContent; // Update the auto-detected format with the new string's characteristics - this._format = TomlFormat.autoDetectFormatWithAst(tomlString, this._ast); + this._format = TomlFormat.autoDetectFormatWithCst(tomlString, this._cst); } } diff --git a/src/toml-format.ts b/src/toml-format.ts index eb3a8a77..a7f5f7ad 100644 --- a/src/toml-format.ts +++ b/src/toml-format.ts @@ -12,11 +12,11 @@ export const DEFAULT_USE_TABS_FOR_INDENTATION = false; export const DEFAULT_MINIMUM_DECIMALS = 0; export const DEFAULT_LEADING_BOM = false; -// Detects if trailing commas are used in the existing TOML by examining the AST +// Detects if trailing commas are used in the existing TOML by examining the CST // Returns true if trailing commas are used, false if not or comma-separated structures found (ie. default to false) -export function detectTrailingComma(ast: Iterable): boolean { +export function detectTrailingComma(cst: Iterable): boolean { // Look for the first inline array or inline table to determine trailing comma preference - for (const item of ast) { + for (const item of cst) { const result = findTrailingCommaInNode(item); if (result !== null) { return result; @@ -28,9 +28,9 @@ export function detectTrailingComma(ast: Iterable): boolean { // Detects if bracket spacing is used in inline arrays and tables by examining the raw string // Returns true if bracket spacing is found, false if not or no bracket structures found (default to true) -export function detectBracketSpacing(tomlString: string, ast: Iterable): boolean { +export function detectBracketSpacing(tomlString: string, cst: Iterable): boolean { // Look for inline arrays and tables - for (const item of ast) { + for (const item of cst) { const result = findBracketSpacingInNode(item, tomlString); if (result !== null) { return result; @@ -333,7 +333,7 @@ export class TomlFormat { /** * The line ending character(s) to use in the output TOML. - * This option affects only the stringification process, not the internal representation (AST). + * This option affects only the stringification process, not the internal representation (CST). * * @example * - '\n' for Unix/Linux line endings @@ -343,7 +343,7 @@ export class TomlFormat { /** * The number of trailing newlines to add at the end of the TOML document. - * This option affects only the stringification process, not the internal representation (AST). + * This option affects only the stringification process, not the internal representation (CST). * * @example * - 0: No trailing newline @@ -500,21 +500,21 @@ export class TomlFormat { * ``` */ static autoDetectFormat(tomlString: string): TomlFormat { - return TomlFormat.autoDetectFormatWithAst(tomlString); + return TomlFormat.autoDetectFormatWithCst(tomlString); } /** - * Internal method: Auto-detects formatting preferences from a TOML string with optional pre-parsed AST. + * Internal method: Auto-detects formatting preferences from a TOML string with optional pre-parsed CST. * - * This is used internally to avoid redundant parsing when the AST is already available. + * This is used internally to avoid redundant parsing when the CST is already available. * External callers should use `autoDetectFormat(tomlString)` instead. * * @internal * @param tomlString - The TOML string to analyze for formatting patterns - * @param syntaxTree - Optional pre-parsed AST to avoid redundant parsing + * @param syntaxTree - Optional pre-parsed CST to avoid redundant parsing * @returns A new TomlFormat instance with detected formatting preferences */ - static autoDetectFormatWithAst(tomlString: string, syntaxTree?: Iterable): TomlFormat { + static autoDetectFormatWithCst(tomlString: string, syntaxTree?: Iterable): TomlFormat { const format = TomlFormat.default(); format.leadingBom = hasLeadingBom(tomlString); // Strip the BOM before other formatting detection to avoid interference. @@ -528,12 +528,12 @@ export class TomlFormat { // Get TOML syntax tree to detect comma and bracket spacing usage patterns try { - // Materialize only when needed so we can traverse the same AST twice. - const astNodes = Array.isArray(syntaxTree) + // Materialize only when needed so we can traverse the same CST twice. + const cstNodes = Array.isArray(syntaxTree) ? syntaxTree : Array.from(syntaxTree ?? parseTOML(tomlContent)); - format.trailingComma = detectTrailingComma(astNodes); - format.bracketSpacing = detectBracketSpacing(tomlContent, astNodes); + format.trailingComma = detectTrailingComma(cstNodes); + format.bracketSpacing = detectBracketSpacing(tomlContent, cstNodes); } catch (error) { // If parsing fails, fall back to defaults // This ensures the method is robust against malformed TOML @@ -559,4 +559,9 @@ export class TomlFormat { return format; } + + /** @deprecated Use autoDetectFormatWithCst instead. */ + static autoDetectFormatWithAst(tomlString: string, syntaxTree?: Iterable): TomlFormat { + return TomlFormat.autoDetectFormatWithCst(tomlString, syntaxTree); + } } diff --git a/src/traverse.ts b/src/traverse.ts index 7bbc0ca6..ce1319d6 100644 --- a/src/traverse.ts +++ b/src/traverse.ts @@ -1,6 +1,6 @@ import { NodeType, - AST, + CST, TreeNode, Document, Table, @@ -44,13 +44,13 @@ export type Visitor = { }; //////////////////////////////////////////////////////////////////////////////// -// The traverse function is used to walk the AST and call the visitor functions +// The traverse function is used to walk the CST and call the visitor functions //////////////////////////////////////////////////////////////////////////////// -export default function traverse(ast: AST | TreeNode, visitor: Visitor) { - if (isIterable(ast)) { - traverseArray(ast, null); +export default function traverse(cst: CST | TreeNode, visitor: Visitor) { + if (isIterable(cst)) { + traverseArray(cst, null); } else { - traverseNode(ast, null); + traverseNode(cst, null); } function traverseArray(array: Iterable, parent: TreeNode | null) { diff --git a/src/truncate.ts b/src/truncate.ts index ef5b6e4d..e254288a 100644 --- a/src/truncate.ts +++ b/src/truncate.ts @@ -1,4 +1,4 @@ -import { AST, Block } from './ast'; +import { CST, Block } from './ast'; import { Position } from './location'; /** @@ -27,41 +27,43 @@ function shouldIncludeBlock(node: Block, limit: Position): boolean { } /** - * Truncates an AST based on a position (line, column) in the source string. + * Truncates a CST based on a position (line, column) in the source string. * - * This function filters the AST to include only the nodes that end before + * This function filters the CST to include only the nodes that end before * the specified position. This ensures that blocks containing changes are * excluded and can be reparsed. This is useful for incremental parsing scenarios - * where you want to keep only the unchanged portion of the AST. + * where you want to keep only the unchanged portion of the CST. * * Special handling: If the truncation point falls within a Table or TableArray * (e.g., in a comment inside the table), the entire table is excluded to ensure * proper reparsing. * - * @param ast - The AST to truncate + * @param cst - The CST to truncate * @param line - The line number (1-indexed) at which to truncate * @param column - The column number (0-indexed) at which to truncate - * @returns An object containing the truncated AST and the end position of the last included node + * @returns An object containing the truncated CST and the end position of the last included node * * @example * ```typescript - * const ast = parseTOML(tomlString); - * // Get AST up to line 5, column 10 (only nodes that end before this position) - * const { truncatedAst, lastEndPosition } = truncateAst(ast, 5, 10); - * for (const node of truncatedAst) { + * const cst = parseTOML(tomlString); + * // Get CST up to line 5, column 10 (only nodes that end before this position) + * const { truncatedCst, lastEndPosition } = truncateCst(cst, 5, 10); + * for (const node of truncatedCst) { * // process node * } * ``` */ -export function truncateAst(ast: AST, line: number, column: number): { - truncatedAst: AST; +export function truncateCst(cst: CST, line: number, column: number): { + truncatedCst: CST; + /** @deprecated Use truncatedCst instead. */ + truncatedAst: CST; lastEndPosition: Position | null } { const limit: Position = { line, column }; const nodes: Block[] = []; let lastEndPosition: Position | null = null; - for (const node of ast) { + for (const node of cst) { const nodeEndsBeforeLimit = comparePositions(node.loc.end, limit) < 0; const nodeStartsBeforeLimit = comparePositions(node.loc.start, limit) < 0; @@ -82,33 +84,34 @@ export function truncateAst(ast: AST, line: number, column: number): { } return { + truncatedCst: nodes, truncatedAst: nodes, lastEndPosition }; } /** - * Finds the last block node in an AST that ends before the specified position. + * Finds the last block node in a CST that ends before the specified position. * - * @param ast - The AST to search + * @param cst - The CST to search * @param line - The line number (1-indexed) * @param column - The column number (0-indexed) * @returns The last block node that ends before the position, or undefined if no such node exists * * @example * ```typescript - * const ast = parseTOML(tomlString); - * const lastNode = findLastNodeBeforePosition(ast, 5, 10); + * const cst = parseTOML(tomlString); + * const lastNode = findLastNodeBeforePosition(cst, 5, 10); * if (lastNode) { * console.log('Last node type:', lastNode.type); * } * ``` */ -export function findLastNodeBeforePosition(ast: AST, line: number, column: number): Block | undefined { +export function findLastNodeBeforePosition(cst: CST, line: number, column: number): Block | undefined { const limit: Position = { line, column }; let lastNode: Block | undefined = undefined; - for (const node of ast) { + for (const node of cst) { if (shouldIncludeBlock(node, limit)) { lastNode = node; } else { @@ -119,3 +122,12 @@ export function findLastNodeBeforePosition(ast: AST, line: number, column: numbe return lastNode; } + +/** @deprecated Use truncateCst instead. */ +export function truncateAst(cst: CST, line: number, column: number): { + truncatedAst: CST; + lastEndPosition: Position | null; +} { + const { truncatedCst, lastEndPosition } = truncateCst(cst, line, column); + return { truncatedAst: truncatedCst, lastEndPosition }; +} diff --git a/src/writer.ts b/src/writer.ts index 090214a6..49410180 100644 --- a/src/writer.ts +++ b/src/writer.ts @@ -34,11 +34,11 @@ import { last } from './utils'; import traverse from './traverse'; //////////////////////////////////////// -// The purpose of this file is to provide a way to modify the AST +// The purpose of this file is to provide a way to modify the CST //////////////////////////////////////// -// Root node of the AST +// Root node of the CST export type Root = Document | TreeNode; // Store line and column offsets per node @@ -126,9 +126,9 @@ export function replace(root: Root, parent: TreeNode, existing: TreeNode, replac dirty_roots.add(root); } /** - * Inserts a child node into the AST. + * Inserts a child node into the CST. * - * @param root - The root node of the AST + * @param root - The root node of the CST * @param parent - The parent node to insert the child into * @param child - The child node to insert * @param index - The index at which to insert the child (optional) @@ -663,12 +663,12 @@ export function applyTrailingComma( } /** - * Applies all accumulated write offsets (enter and exit) to the given AST node. + * Applies all accumulated write offsets (enter and exit) to the given CST node. * This function adjusts the start and end locations of each node in the tree based on * the offsets stored in the `enter` and `exit` maps. It ensures that the tree's location * data is consistent after modifications. * - * @param root - The root node of the AST tree to which the write offsets will be applied. + * @param root - The root node of the CST tree to which the write offsets will be applied. */ export function applyWrites(root: TreeNode) { if (!dirty_roots.has(root)) return; From b363f84ac97c216e91334eee06c8bf878d6d624f Mon Sep 17 00:00:00 2001 From: Martin Leduc <31558169+DecimalTurn@users.noreply.github.com> Date: Tue, 12 May 2026 11:14:51 -0400 Subject: [PATCH 2/4] refactor: remove internal depreciated members --- src/__tests__/truncate.test.ts | 14 +++++++------- src/__tests__/validate-ast.test.ts | 2 +- src/ast.ts | 3 --- src/patch.ts | 3 --- src/truncate.ts | 12 ------------ 5 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/__tests__/truncate.test.ts b/src/__tests__/truncate.test.ts index 60a203a4..391832dd 100644 --- a/src/__tests__/truncate.test.ts +++ b/src/__tests__/truncate.test.ts @@ -4,7 +4,7 @@ import toJS from '../to-js'; import { NodeType } from '../ast'; import dedent from 'dedent'; -describe('truncateAst', () => { +describe('truncateCst', () => { it('truncates CST at specified position', () => { const toml = dedent` [section1] @@ -18,7 +18,7 @@ describe('truncateAst', () => { // Truncate at line 3 (before section2) const { truncatedCst, lastEndPosition } = truncateCst(cst, 3, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({ section1: { key1: 'value1' } }); @@ -38,7 +38,7 @@ describe('truncateAst', () => { // Truncate at a position beyond the document const { truncatedCst, lastEndPosition } = truncateCst(cst, 100, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({ section1: { key1: 'value1' }, section2: { key2: 'value2' } @@ -56,7 +56,7 @@ describe('truncateAst', () => { // Truncate at line 0 (before everything) const { truncatedCst, lastEndPosition } = truncateCst(cst, 0, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({}); expect(lastEndPosition).toBeNull(); }); @@ -97,7 +97,7 @@ describe('truncateAst', () => { // So only "a = 1" which ends at line 1 const { truncatedCst, lastEndPosition } = truncateCst(cst, 2, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({ a: 1 }); expect(lastEndPosition).not.toBeNull(); }); @@ -118,7 +118,7 @@ describe('truncateAst', () => { // Truncate to include only first two products const { truncatedCst, lastEndPosition } = truncateCst(cst, 6, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({ products: [ { name: 'Product 1' }, @@ -146,7 +146,7 @@ describe('truncateAst', () => { // So only [parent.child1] which ends at line 2 const { truncatedCst, lastEndPosition } = truncateCst(cst, 5, 0); - const result = toJS(truncatedAst); + const result = toJS(truncatedCst); expect(result).toEqual({ parent: { child1: { key1: 1 } diff --git a/src/__tests__/validate-ast.test.ts b/src/__tests__/validate-ast.test.ts index 2421e2db..6cba5404 100644 --- a/src/__tests__/validate-ast.test.ts +++ b/src/__tests__/validate-ast.test.ts @@ -212,7 +212,7 @@ function expectConsistent(toml: string, updated: any) { // --------------------------------------------------------------------------- /** - * These tests check whether the CST returned by patchAst() has consistent + * These tests check whether the CST returned by patchCst() has consistent * position metadata after modifications (no parent-child location overlaps). * * The TOML string output is always correct — toTOML serializes from the CST diff --git a/src/ast.ts b/src/ast.ts index ef8eb92c..47d339b4 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -34,9 +34,6 @@ export enum NodeType { // export type CST = Iterable; -/** @deprecated Use CST instead. */ -export type AST = CST; - // // Document // diff --git a/src/patch.ts b/src/patch.ts index 24bd5fee..ef5e55fa 100644 --- a/src/patch.ts +++ b/src/patch.ts @@ -126,9 +126,6 @@ export function patchCst(existing_cst: CST, updated: any, format: TomlFormat): { }; } -/** @deprecated Use patchCst instead. */ -export const patchAst = patchCst; - function reorder(changes: Change[]): Change[] { //Reorder deletions among themselves to avoid index issues // We want the path to be looking at the last item in the array first and go down from there diff --git a/src/truncate.ts b/src/truncate.ts index e254288a..d3d42088 100644 --- a/src/truncate.ts +++ b/src/truncate.ts @@ -55,8 +55,6 @@ function shouldIncludeBlock(node: Block, limit: Position): boolean { */ export function truncateCst(cst: CST, line: number, column: number): { truncatedCst: CST; - /** @deprecated Use truncatedCst instead. */ - truncatedAst: CST; lastEndPosition: Position | null } { const limit: Position = { line, column }; @@ -85,7 +83,6 @@ export function truncateCst(cst: CST, line: number, column: number): { return { truncatedCst: nodes, - truncatedAst: nodes, lastEndPosition }; } @@ -122,12 +119,3 @@ export function findLastNodeBeforePosition(cst: CST, line: number, column: numbe return lastNode; } - -/** @deprecated Use truncateCst instead. */ -export function truncateAst(cst: CST, line: number, column: number): { - truncatedAst: CST; - lastEndPosition: Position | null; -} { - const { truncatedCst, lastEndPosition } = truncateCst(cst, line, column); - return { truncatedAst: truncatedCst, lastEndPosition }; -} From 9ea28f012544bf42d9def8be320ff773a4dd0409 Mon Sep 17 00:00:00 2001 From: Martin Leduc <31558169+DecimalTurn@users.noreply.github.com> Date: Tue, 12 May 2026 11:20:41 -0400 Subject: [PATCH 3/4] refactor: file renaming "ast" to "cst" --- .../{ast-parsing.test.ts.snap => cst-parsing.test.ts.snap} | 0 src/__tests__/{ast-parsing.test.ts => cst-parsing.test.ts} | 0 src/__tests__/find-by-path.test.ts | 2 +- src/__tests__/generate.test.ts | 2 +- src/__tests__/parse-js.test.ts | 2 +- src/__tests__/parse-toml.test.ts | 2 +- src/__tests__/truncate.test.ts | 2 +- src/__tests__/{validate-ast.test.ts => validate-cst.test.ts} | 2 +- src/__tests__/writer.test.ts | 2 +- src/comment-alignment.ts | 2 +- src/{ast.ts => cst.ts} | 0 src/find-by-path.ts | 2 +- src/formatter.ts | 2 +- src/generate.ts | 2 +- src/parse-js.ts | 2 +- src/parse-toml.ts | 2 +- src/patch.ts | 2 +- src/to-js.ts | 2 +- src/to-toml.ts | 2 +- src/toml-document.ts | 2 +- src/traverse.ts | 2 +- src/truncate.ts | 2 +- src/writer.ts | 2 +- 23 files changed, 20 insertions(+), 20 deletions(-) rename src/__tests__/__snapshots__/{ast-parsing.test.ts.snap => cst-parsing.test.ts.snap} (100%) rename src/__tests__/{ast-parsing.test.ts => cst-parsing.test.ts} (100%) rename src/__tests__/{validate-ast.test.ts => validate-cst.test.ts} (99%) rename src/{ast.ts => cst.ts} (100%) diff --git a/src/__tests__/__snapshots__/ast-parsing.test.ts.snap b/src/__tests__/__snapshots__/cst-parsing.test.ts.snap similarity index 100% rename from src/__tests__/__snapshots__/ast-parsing.test.ts.snap rename to src/__tests__/__snapshots__/cst-parsing.test.ts.snap diff --git a/src/__tests__/ast-parsing.test.ts b/src/__tests__/cst-parsing.test.ts similarity index 100% rename from src/__tests__/ast-parsing.test.ts rename to src/__tests__/cst-parsing.test.ts diff --git a/src/__tests__/find-by-path.test.ts b/src/__tests__/find-by-path.test.ts index 5b4ce035..2d51536f 100644 --- a/src/__tests__/find-by-path.test.ts +++ b/src/__tests__/find-by-path.test.ts @@ -1,7 +1,7 @@ import findByPath from '../find-by-path'; import parseTOML from '../parse-toml'; import { example } from '../__fixtures__'; -import { Document, NodeType } from '../ast'; +import { Document, NodeType } from '../cst'; import dedent from 'dedent'; it('should find node by path', () => { diff --git a/src/__tests__/generate.test.ts b/src/__tests__/generate.test.ts index 099ba01d..47d54180 100644 --- a/src/__tests__/generate.test.ts +++ b/src/__tests__/generate.test.ts @@ -1,5 +1,5 @@ import { generateString } from '../generate'; -import { NodeType } from '../ast'; +import { NodeType } from '../cst'; describe('generateString', () => { describe('with multiline basic string format preservation', () => { diff --git a/src/__tests__/parse-js.test.ts b/src/__tests__/parse-js.test.ts index 67f6b9a2..aa822337 100644 --- a/src/__tests__/parse-js.test.ts +++ b/src/__tests__/parse-js.test.ts @@ -2,7 +2,7 @@ import parseJS from '../parse-js'; import parseTOML from '../parse-toml'; import toTOML from '../to-toml'; import dedent from 'dedent'; -import { NodeType, CST, Document } from '../ast'; +import { NodeType, CST, Document } from '../cst'; import { TomlFormat } from '../toml-format'; function toDocument(cst: CST): Document { diff --git a/src/__tests__/parse-toml.test.ts b/src/__tests__/parse-toml.test.ts index 2ee22c3d..486fe5d5 100644 --- a/src/__tests__/parse-toml.test.ts +++ b/src/__tests__/parse-toml.test.ts @@ -1,5 +1,5 @@ import parseTOML from '../parse-toml'; -import { Table, KeyValue, InlineArray, DateTime } from '../ast'; +import { Table, KeyValue, InlineArray, DateTime } from '../cst'; import { example, fruit, hard_example, hard_example_unicode, kitchen_sink } from '../__fixtures__'; import dedent from 'dedent'; diff --git a/src/__tests__/truncate.test.ts b/src/__tests__/truncate.test.ts index 391832dd..c8c2dd8f 100644 --- a/src/__tests__/truncate.test.ts +++ b/src/__tests__/truncate.test.ts @@ -1,7 +1,7 @@ import parseTOML from '../parse-toml'; import { truncateCst, findLastNodeBeforePosition } from '../truncate'; import toJS from '../to-js'; -import { NodeType } from '../ast'; +import { NodeType } from '../cst'; import dedent from 'dedent'; describe('truncateCst', () => { diff --git a/src/__tests__/validate-ast.test.ts b/src/__tests__/validate-cst.test.ts similarity index 99% rename from src/__tests__/validate-ast.test.ts rename to src/__tests__/validate-cst.test.ts index 6cba5404..960e2570 100644 --- a/src/__tests__/validate-ast.test.ts +++ b/src/__tests__/validate-cst.test.ts @@ -1,7 +1,7 @@ import { Document, NodeType, TreeNode, Table, TableArray, InlineArray, InlineTable, InlineItem, KeyValue -} from '../ast'; +} from '../cst'; import { Location, Position } from '../location'; import parseTOML from '../parse-toml'; import { patchCst } from '../patch'; diff --git a/src/__tests__/writer.test.ts b/src/__tests__/writer.test.ts index 10d5ff0e..5251bb38 100644 --- a/src/__tests__/writer.test.ts +++ b/src/__tests__/writer.test.ts @@ -8,7 +8,7 @@ import { generateDocument } from '../generate'; import { TomlFormat } from '../toml-format'; -import { String as StringNode, NodeType } from '../ast'; +import { String as StringNode, NodeType } from '../cst'; test('it should insert elements into empty inline array', () => { const inline_array = generateInlineArray(); diff --git a/src/comment-alignment.ts b/src/comment-alignment.ts index 8fc5491f..31aa15fb 100644 --- a/src/comment-alignment.ts +++ b/src/comment-alignment.ts @@ -26,7 +26,7 @@ import { isKeyValue, isTable, isTableArray -} from './ast'; +} from './cst'; import { getSpan } from './location'; import { TomlFormat } from './toml-format'; diff --git a/src/ast.ts b/src/cst.ts similarity index 100% rename from src/ast.ts rename to src/cst.ts diff --git a/src/find-by-path.ts b/src/find-by-path.ts index b0251f9e..81cabc87 100644 --- a/src/find-by-path.ts +++ b/src/find-by-path.ts @@ -1,4 +1,4 @@ -import { TreeNode, isKeyValue, isTable, isTableArray, isDocument, hasItems, isInlineItem, Document, Table, TableArray, Block } from './ast'; +import { TreeNode, isKeyValue, isTable, isTableArray, isDocument, hasItems, isInlineItem, Document, Table, TableArray, Block } from './cst'; import { arraysEqual, stableStringify } from './utils'; export type Path = Array; diff --git a/src/formatter.ts b/src/formatter.ts index 841d3bcc..fba114b4 100644 --- a/src/formatter.ts +++ b/src/formatter.ts @@ -10,7 +10,7 @@ import { isTableArray, Document, TreeNode -} from './ast'; +} from './cst'; import { generateTable, generateDocument, generateTableArray } from './generate'; import { insert, remove, applyWrites, shiftNode } from './writer'; import { TomlFormat } from './toml-format'; diff --git a/src/generate.ts b/src/generate.ts index 889c1663..e2d8d90d 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -22,7 +22,7 @@ import { InlineItem, InlineTable, Comment -} from './ast'; +} from './cst'; import { zero, cloneLocation, clonePosition, Position } from './location'; import { LocalDate } from './parse-toml'; import { shiftNode } from './writer'; diff --git a/src/parse-js.ts b/src/parse-js.ts index a312ddff..ae154b5e 100644 --- a/src/parse-js.ts +++ b/src/parse-js.ts @@ -1,4 +1,4 @@ -import { Value, KeyValue, Document, InlineArray, InlineTable } from './ast'; +import { Value, KeyValue, Document, InlineArray, InlineTable } from './cst'; import { generateDocument, generateKeyValue, diff --git a/src/parse-toml.ts b/src/parse-toml.ts index 71c044d4..83a03b46 100644 --- a/src/parse-toml.ts +++ b/src/parse-toml.ts @@ -17,7 +17,7 @@ import { Comment, CST, Block -} from './ast'; +} from './cst'; import { Token, TokenType, tokenize, DOUBLE_QUOTE, SINGLE_QUOTE } from './tokenizer'; import { parseString } from './parse-string'; import Cursor from './cursor'; diff --git a/src/patch.ts b/src/patch.ts index ef5e55fa..8814d7b6 100644 --- a/src/patch.ts +++ b/src/patch.ts @@ -25,7 +25,7 @@ import { Table, Value, isDateTime -} from './ast'; +} from './cst'; import diff, { Change, isAdd, isEdit, isRemove, isMove, isRename } from './diff'; import findByPath, { tryFindByPath, findParent } from './find-by-path'; import { last, isInteger } from './utils'; diff --git a/src/to-js.ts b/src/to-js.ts index 287f5ccd..7277cc51 100644 --- a/src/to-js.ts +++ b/src/to-js.ts @@ -1,4 +1,4 @@ -import { Value, NodeType, TreeNode, CST, InlineTable, Table, TableArray, KeyValue } from './ast'; +import { Value, NodeType, TreeNode, CST, InlineTable, Table, TableArray, KeyValue } from './cst'; import { last, blank, isDate, has } from './utils'; import ParseError from './parse-error'; import { IntegersAsBigInt } from './parse-options'; diff --git a/src/to-toml.ts b/src/to-toml.ts index 1f0460f0..ac0c7e9a 100644 --- a/src/to-toml.ts +++ b/src/to-toml.ts @@ -18,7 +18,7 @@ import { InlineTable, InlineItem, Comment -} from './ast'; +} from './cst'; import { Location } from './location'; import { SPACE } from './tokenizer'; import { TomlFormat } from './toml-format'; diff --git a/src/toml-document.ts b/src/toml-document.ts index d6a10948..211ffee6 100644 --- a/src/toml-document.ts +++ b/src/toml-document.ts @@ -1,7 +1,7 @@ import parseTOML, { continueParsingTOML } from './parse-toml'; import toJS from './to-js'; import { TomlFormat } from './toml-format'; -import { Block } from './ast'; +import { Block } from './cst'; import { patchCst } from './patch'; import { detectNewline, resolveTomlFormat } from './toml-format'; import { truncateCst } from './truncate'; diff --git a/src/traverse.ts b/src/traverse.ts index ce1319d6..cb6d713c 100644 --- a/src/traverse.ts +++ b/src/traverse.ts @@ -18,7 +18,7 @@ import { InlineArray, InlineTable, InlineItem -} from './ast'; +} from './cst'; import { isIterable } from './utils'; export type Visit = (node: TNode, parent: TNode | null) => void; diff --git a/src/truncate.ts b/src/truncate.ts index d3d42088..3c9f7ad4 100644 --- a/src/truncate.ts +++ b/src/truncate.ts @@ -1,4 +1,4 @@ -import { CST, Block } from './ast'; +import { CST, Block } from './cst'; import { Position } from './location'; /** diff --git a/src/writer.ts b/src/writer.ts index 49410180..6af4744c 100644 --- a/src/writer.ts +++ b/src/writer.ts @@ -28,7 +28,7 @@ import { Block, isBlock, WithItems -} from './ast'; +} from './cst'; import { Span, getSpan, clonePosition } from './location'; import { last } from './utils'; import traverse from './traverse'; From 72551f3dba2b7aaa9c2bdd84e2c784f13a71d90d Mon Sep 17 00:00:00 2001 From: Martin Leduc <31558169+DecimalTurn@users.noreply.github.com> Date: Tue, 12 May 2026 17:55:38 -0400 Subject: [PATCH 4/4] refactor: remove non-needed get properties --- src/toml-document.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/toml-document.ts b/src/toml-document.ts index 211ffee6..8e19e158 100644 --- a/src/toml-document.ts +++ b/src/toml-document.ts @@ -61,16 +61,6 @@ export class TomlDocument { return this._cst; } - /** @deprecated Use cst instead. */ - get CST(): Block[] { - return this._cst; - } - - /** @deprecated Use cst instead. */ - get ast(): Block[] { - return this._cst; - } - /** * Applies a patch to the current CST using a modified JS object. * Updates the internal CST. Use toTomlString getter to retrieve the updated TOML string.