tstosc
Version:
A transpiler that convert TypeScript to SuperCollider's SCLang.
105 lines (99 loc) • 4.55 kB
JavaScript
;
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;