Skip to content

Commit

Permalink
add stricter assertion into fill()
Browse files Browse the repository at this point in the history
  • Loading branch information
seiyab committed Sep 13, 2024
1 parent 84b5a80 commit cb708fb
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
8 changes: 6 additions & 2 deletions src/document/builders.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
DOC_TYPE_LINE_SUFFIX_BOUNDARY,
DOC_TYPE_TRIM,
} from "./constants.js";
import { assertDoc, assertDocArray } from "./utils/assert-doc.js";
import {
assertDoc,
assertDocArray,
assertDocFill,
} from "./utils/assert-doc.js";

/**
* TBD properly tagged union for Doc object type is needed here.
Expand Down Expand Up @@ -106,7 +110,7 @@ function conditionalGroup(states, opts) {
* @returns Doc
*/
function fill(parts) {
assertDocArray(parts);
assertDocFill(parts);

return { type: DOC_TYPE_FILL, parts };
}
Expand Down
64 changes: 63 additions & 1 deletion src/document/utils/assert-doc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import {
DOC_TYPE_IF_BREAK,
DOC_TYPE_LINE,
DOC_TYPE_STRING,
} from "../constants.js";
import getDocType from "./get-doc-type.js";
import traverseDoc from "./traverse-doc.js";

/**
* @typedef {import("../builders.js").Doc} Doc
*/

const checked = process.env.NODE_ENV !== "production" && new WeakSet();
const noop = () => {};
const assertDoc =
Expand Down Expand Up @@ -34,4 +44,56 @@ const assertDocArray =
}
};

export { assertDoc, assertDocArray };
const assertDocFill =
process.env.NODE_ENV === "production"
? noop
: /**
* @param {Doc[]} parts
*/
function (parts) {
assertDocArray(parts);
for (const [i, doc] of parts.entries()) {
if (i % 2 === 0) {
continue;
}
if (!isValidSeparator(doc)) {
const type = getDocType(doc);
throw new Error(
`Unexpected non-line-break doc at ${i}. Doc type is ${type}.`,
);
}
}
};

/**
* @param {Doc} doc
* @returns {boolean}
*/
function isValidSeparator(doc) {
let hasLine = false;
let hasString = false;
traverseDoc(doc, (doc) => {
switch (getDocType(doc)) {
case DOC_TYPE_LINE:
hasLine = true;
return;
case DOC_TYPE_STRING:
hasString = true;
return;
case DOC_TYPE_IF_BREAK:
traverseDoc(doc.breakContents, (doc) => {
switch (getDocType(doc)) {
case DOC_TYPE_LINE:
hasLine = true;
// We don't check hasString here
// We sometimes need string in breakContents like `ifBreak([`{" "}`, line])`
}
});
return false;
default:
}
});
return hasLine && !hasString;
}

export { assertDoc, assertDocArray, assertDocFill };

0 comments on commit cb708fb

Please sign in to comment.