Files
infocom-systems-design/node_modules/langium/lib/generate/node-joiner.js
2025-10-03 22:27:28 +03:00

58 lines
3.4 KiB
JavaScript

/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { isGeneratorNode } from './generator-node.js';
import { CompositeGeneratorNode, traceToNode } from './generator-node.js';
const defaultToGenerated = (e) => e === undefined || typeof e === 'string' || isGeneratorNode(e) ? e : String(e);
export function joinToNode(iterable, toGeneratedOrOptions = defaultToGenerated, options = {}) {
const toGenerated = typeof toGeneratedOrOptions === 'function' ? toGeneratedOrOptions : defaultToGenerated;
const { filter, prefix, suffix, separator, appendNewLineIfNotEmpty, skipNewLineAfterLastItem } = typeof toGeneratedOrOptions === 'object' ? toGeneratedOrOptions : options;
const prefixFunc = typeof prefix === 'function' ? prefix : (() => prefix);
const suffixFunc = typeof suffix === 'function' ? suffix : (() => suffix);
return reduceWithIsLast(iterable, (node, it, i, isLast) => {
if (filter && !filter(it, i, isLast)) {
return node;
}
const content = toGenerated(it, i, isLast);
return content === undefined ? /* in this case don't append anything to */ node : /* otherwise: */ (node !== null && node !== void 0 ? node : (node = new CompositeGeneratorNode()))
.append(prefixFunc(it, i, isLast))
.append(content)
.append(suffixFunc(it, i, isLast))
.appendIf(!isLast, separator)
.appendNewLineIfNotEmptyIf(
// append 'newLineIfNotEmpty' elements only if 'node' has some content already,
// as if the parent is an IndentNode with 'indentImmediately' set to 'false'
// the indentation is not properly applied to the first non-empty line of the (this) child node
// besides, append the newLine only if more lines are following, if appending a newline
// is not suppressed for the final item
!node.isEmpty() && !!appendNewLineIfNotEmpty && (!isLast || !skipNewLineAfterLastItem));
});
}
// implementation:
export function joinTracedToNode(source, property) {
return (iterable, toGeneratedOrOptions, options) => {
options !== null && options !== void 0 ? options : (options = typeof toGeneratedOrOptions === 'object' ? toGeneratedOrOptions : undefined);
const toGenerated = typeof toGeneratedOrOptions === 'function' ? toGeneratedOrOptions : defaultToGenerated;
return traceToNode(source, property)(joinToNode(iterable, source && property ? (element, index, isLast) => traceToNode(source, property, index)(toGenerated(element, index, isLast)) : toGenerated, options));
};
}
// implementation:
export function joinTracedToNodeIf(condition, source, property) {
return condition ? joinTracedToNode((typeof source === 'function' ? source() : source), property) : () => undefined;
}
function reduceWithIsLast(iterable, callbackfn, initial) {
const iterator = iterable[Symbol.iterator]();
let next = iterator.next();
let index = 0;
let result = initial;
while (!next.done) {
const nextNext = iterator.next();
result = callbackfn(result, next.value, index, Boolean(nextNext.done));
next = nextNext;
index++;
}
return result;
}
//# sourceMappingURL=node-joiner.js.map