UNPKG

haystack-codegen

Version:

Project Haystack Core code generation tools

234 lines (233 loc) 6.14 kB
"use strict"; /* * 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;