UNPKG

tstosc

Version:

A transpiler that convert TypeScript to SuperCollider's SCLang.

105 lines (99 loc) 4.55 kB
'use strict'; var ts = require('typescript'); var context_cjs = require('../context.cjs'); var stmt_conv_cjs = require('./stmt_conv.cjs'); var name_decl_def_hoist_cjs = require('../name_decl_def_hoist.cjs'); var expr_conv_cjs = require('./expr_conv.cjs'); var util_cjs = require('../../../util/util.cjs'); var Result_cjs = require('../../../util/Result.cjs'); var class_conv_cjs = require('./class_conv.cjs'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var ts__default = /*#__PURE__*/_interopDefault(ts); const default_convert_file_option = { convert_file: true, convert_class: true }; function convertTSSourceFileToSC(source_file, generator_context = context_cjs.default_generator_context, option_from_user = default_convert_file_option) { const option = { ...default_convert_file_option, ...option_from_user }; const preprocessing_pack = findPreprocessingNeededByCached(source_file); generator_context = { ...generator_context, ...preprocessing_pack.exceptional_syntax }; generator_context.is_standalone_statement = true; let result = { file: "", class: "" }; try { if (option.convert_file) { const def_decl_stmts = name_decl_def_hoist_cjs.generateVarConstDeclarationAndDefinition(source_file); result.file = def_decl_stmts + (def_decl_stmts.length > 0 ? "\n" : "") + generateHelperEnvironment(preprocessing_pack.exceptional_syntax, generator_context) + source_file.statements.map((s) => stmt_conv_cjs.convertTSStatementToSC(s, generator_context)).filter((s) => s.length > 0).join("\n"); } if (option.convert_class) { result.class = preprocessing_pack.class_definitions.map( ({ name, definition }) => class_conv_cjs.convertTSClassToSCWithClassName(definition, name, generator_context) ).join("\n\n"); } } catch (err) { return Result_cjs.Result.createErr(err); } return Result_cjs.Result.createOk(result); } const findPreprocessingNeededByCached = util_cjs.memorised( findPreprocessingNeeded, function makeKey(source_file) { return source_file.fileName; } ); function findPreprocessingNeeded(source_file) { let exceptional_syntax = { has_unhandled_self_indecr_operator: false }; let class_definitions = []; function traverse(node) { if (!exceptional_syntax.has_unhandled_self_indecr_operator && expr_conv_cjs.isSelfIndecrExpression(node)) { exceptional_syntax.has_unhandled_self_indecr_operator = true; } else if (ts__default.default.isClassDeclaration(node)) { class_definitions.push({ name: escapeToSCClassName(node.name?.text ?? `${source_file.fileName.replace(/^[\.\/]|\.ts$/, "")}__default_export`), definition: node }); } else if (ts__default.default.isClassExpression(node)) { let getVariableDeclarationParent2 = function(n) { if (ts__default.default.isVariableDeclaration(n)) { return n; } else { return getVariableDeclarationParent2(n.parent); } }; const { name: pattern, initializer: initialiser } = getVariableDeclarationParent2(node); const def_decl_collection = name_decl_def_hoist_cjs.solveRecurBinding(pattern, initialiser); class_definitions.push( ...def_decl_collection.filter((d) => d[1] != void 0 && ts__default.default.isClassExpression(d[1])).map(([name, definition]) => ({ name, definition })) ); } { node.forEachChild(traverse); } } traverse(source_file); return { exceptional_syntax, class_definitions }; } function escapeToSCClassName(name) { if (name.length == 0) { throw TypeError(`The class name to escape is empty.`); } name = name.replace(/[^\w]/g, "_"); return name[0].toUpperCase() + name.slice(1); } function generateHelperEnvironment(exceptional_syntax, generator_context) { let result = []; if (exceptional_syntax.has_unhandled_self_indecr_operator) { result.push(...[ "~tstosc__pre_incr = {|r|r.value=r.value+1;r.value} ;", "~tstosc__post_incr = {|r|var t=r.value;r.value=r.value+1;t} ;", "~tstosc__pre_decr = {|r|r.value=r.value-1;r.value} ;", "~tstosc__post_decr = {|r|var t=r.value;r.value=r.value-1;t} ;" ]); } return result.length > 0 ? "/* Helper Environment */\n" + result.join("\n") + "\n\n" : ""; } exports.convertTSSourceFileToSC = convertTSSourceFileToSC; exports.default_convert_file_option = default_convert_file_option; exports.findPreprocessingNeeded = findPreprocessingNeeded; exports.findPreprocessingNeededByCached = findPreprocessingNeededByCached;