haystack-codegen
Version:
Project Haystack Core code generation tools
234 lines (233 loc) • 6.14 kB
JavaScript
;
/*
* Copyright (c) 2021, J2 Innovations. All Rights Reserved
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeDocComment = exports.convertKindToCtorName = exports.capitalizeFirstChar = exports.makeTypeName = exports.generateCodeFromNode = exports.generateNodes = void 0;
const haystack_core_1 = require("haystack-core");
const RESERVED_NAMES = new Set();
[
'Date',
'Kind',
'HBool',
'HCoord',
'HDate',
'HDateTime',
'HDict',
'HGrid',
'HList',
'HMarker',
'HNa',
'HNum',
'HRef',
'HRemove',
'HStr',
'HSymbol',
'HTime',
'HXStr',
'HNamespace',
'HUri',
'valueIsKind',
'Number',
'Symbol',
'String',
'Array',
'Boolean',
'Function',
'AsyncFunction',
'Object',
'Array',
'Map',
'Set',
'BigInt',
'Blob',
'ArrayBuffer',
'BigInt64Array',
'BigUint64Array',
'Float32Array',
'Float64Array',
'Image',
'Int16Array',
'Int32Array',
'Int8Array',
'UInt16Array',
'UInt32Array',
'UInt8Array',
'Uint8ClampedArray',
'clearInterval',
'setInterval',
'clearTimeout',
'setTimeout',
'JSON',
'ServerWorker',
'URL',
'WeakSet',
'WeakMap',
'WeakRef',
'RegExp',
'Window',
'Undefined',
'Null',
'WebAssembly',
'URIError',
'TypeError',
'TypedArray',
'SyntaxError',
'SharedArrayBuffer',
'Reflect',
'ReferenceError',
'RangeError',
'Proxy',
'Promise',
'NaN',
'Math',
'isNaN',
'isFinite',
'Intl',
'InternalError',
'Infinity',
'eval',
'Error',
'DateView',
'Atomics',
'AggregateError',
].forEach((name) => RESERVED_NAMES.add(name));
/**
* Generate the code string from a group of nodes.
*
* @param out The output to write too.
* @param nodes The nodes.
* @returns The code.
*/
function generateNodes(out, nodes) {
for (const node of nodes) {
let isEmpty = true;
node.generateCode((code) => {
if (code) {
isEmpty = false;
}
out(code);
});
if (!isEmpty) {
for (let i = 0; i < node.newLines; ++i) {
out('');
}
}
}
}
exports.generateNodes = generateNodes;
/**
* Return the generated code from the node.
*
* @param node The node to run.
* @returns The generated code.
*/
function generateCodeFromNode(node) {
let str = '';
node.generateCode((code) => {
str += code + '\n';
});
return str;
}
exports.generateCodeFromNode = generateCodeFromNode;
/**
* Return a name that can be used as a type.
*
* @param def The def name to create a type name from.
* @param nameToDefCache A name to def cache.
* @returns The type name.
*/
function makeTypeName(def, nameToDefCache) {
if (!def) {
throw new Error(`Invalid interface name: ${def}`);
}
let name = def;
if (haystack_core_1.HNamespace.isConjunct(def)) {
name = haystack_core_1.HNamespace.splitConjunct(def)
.map((nm, i) => (i > 0 ? capitalizeFirstChar(nm) : nm))
.join('_');
}
else if (haystack_core_1.HNamespace.isFeature(def)) {
name = def.split(':')[1];
}
name = capitalizeFirstChar(name);
if (RESERVED_NAMES.has(name)) {
name = `I${name}`;
}
while (nameToDefCache[name] && nameToDefCache[name] !== def) {
name += '_';
}
nameToDefCache[name] = def;
return name;
}
exports.makeTypeName = makeTypeName;
/**
* Capitalize the first character of the string.
*
* @param str The string to capitalize the first letter of.
* @returns A string with the first letter being a capital.
*/
function capitalizeFirstChar(str) {
return str && str.length > 0
? `${str[0].toUpperCase()}${str.substring(1, str.length)}`
: '';
}
exports.capitalizeFirstChar = capitalizeFirstChar;
/**
* Convert the haystack kind to the name of the `haystack-core` contructor name.
*
* @param kind The haystack kind value.
* @returns The constructor name.
* @throws If the kind is unsupported or invalid.
*/
function convertKindToCtorName(kind) {
switch (kind) {
case haystack_core_1.Kind.Bool:
return haystack_core_1.HBool.name;
case haystack_core_1.Kind.Coord:
return haystack_core_1.HCoord.name;
case haystack_core_1.Kind.Date:
return haystack_core_1.HDate.name;
case haystack_core_1.Kind.DateTime:
return haystack_core_1.HDateTime.name;
case haystack_core_1.Kind.Dict:
return haystack_core_1.HDict.name;
case haystack_core_1.Kind.Grid:
return haystack_core_1.HGrid.name;
case haystack_core_1.Kind.List:
return haystack_core_1.HList.name;
case haystack_core_1.Kind.Marker:
return haystack_core_1.HMarker.name;
case haystack_core_1.Kind.NA:
return haystack_core_1.HNa.name;
case haystack_core_1.Kind.Number:
return haystack_core_1.HNum.name;
case haystack_core_1.Kind.Ref:
return haystack_core_1.HRef.name;
case haystack_core_1.Kind.Remove:
return haystack_core_1.HRemove.name;
case haystack_core_1.Kind.Str:
return haystack_core_1.HStr.name;
case haystack_core_1.Kind.Symbol:
return haystack_core_1.HSymbol.name;
case haystack_core_1.Kind.Time:
return haystack_core_1.HTime.name;
case haystack_core_1.Kind.XStr:
return haystack_core_1.HXStr.name;
case haystack_core_1.Kind.Uri:
return haystack_core_1.HUri.name;
default:
throw new Error(`Unsupported kind: ${kind}`);
}
}
exports.convertKindToCtorName = convertKindToCtorName;
/**
* Write the document comments.
*
* @param out Used to output the code.
* @param doc The documentation to write.
*/
function writeDocComment(out, doc) {
doc.split('\n').forEach((line) => out(` * ${line.trim()}`));
}
exports.writeDocComment = writeDocComment;