UNPKG

rooibos-roku

Version:

simple, flexible, fun brightscript test framework for roku scenegraph apps - roku brighterscript plugin

144 lines 6.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getScopeForSuite = exports.getPathValuePartAsString = exports.getStringPathFromDottedGet = exports.getRootObjectFromDottedGet = exports.getAllDottedGetParts = exports.functionRequiresReturnValue = exports.sanitizeBsJsonString = exports.addOverriddenMethod = void 0; const brighterscript_1 = require("brighterscript"); const Diagnostics_1 = require("../utils/Diagnostics"); function addOverriddenMethod(file, annotation, target, name, source, editor) { var _a, _b; let { method, diagnostics, text } = createMethod(file, name, source); if (method.func.body.statements.length > 0) { //bsc has a quirk where it auto-adds a `new` method if missing. That messes with our AST editing, so //trigger that functionality BEFORE performing AstEditor operations. TODO remove this whenever bsc stops doing this. (_b = (_a = target).ensureConstructorFunctionExists) === null || _b === void 0 ? void 0 : _b.call(_a); editor.addToArray(target.body, target.body.length, method); return true; } const error = (diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.length) > 0 ? diagnostics[0].message : 'unknown error'; (0, Diagnostics_1.diagnosticCorruptTestProduced)(file, annotation, error, text); return false; } exports.addOverriddenMethod = addOverriddenMethod; /** * Create a new MethodStatement instance with the given name and body. * * This is a HACK to be able to build the same MethodStatement instance as the version of brighterscript we're running against. (because otherwise, some older versions * of bsc (like the one rooibos depends on) have a bug that doesn't transpile the method name correctly in some instances) * @param file any file from the host program's version of BrighterScript. (we're going to utilize its `constructor` and `parse` functions to create a new MethodStatement instance) * @param name name of the method to create * @param body string text containing the body of the method */ function createMethod(file, name, body) { const text = ` class RooibosTemplateClass public override function ${name}() ${body} end function end class `; try { //parse a new instance of a file, so we can abuse its `parse` function, which will use the _current_ version of the MethodStatement class const f = new file.constructor(file.srcPath, file.pkgPath, file.program); f.parse(text); return { method: f.ast.statements[0].body[0], text: text, diagnostics: f.diagnostics }; } catch (e) { console.error(`Error generating method '${name}' while using the host bsc version. Falling back to embedded Parser.parse`, { cause: e }); const { statements, diagnostics } = brighterscript_1.Parser.parse(text, { mode: brighterscript_1.ParseMode.BrighterScript }); return { method: statements[0].body[0], text: text, diagnostics: diagnostics }; } } function sanitizeBsJsonString(text) { return `"${text ? text.replace(/"/g, '\'') : ''}"`; } exports.sanitizeBsJsonString = sanitizeBsJsonString; function functionRequiresReturnValue(statement) { const returnTypeToken = statement.func.returnTypeToken; const functionType = statement.func.functionType; return !(((functionType === null || functionType === void 0 ? void 0 : functionType.kind) === brighterscript_1.TokenKind.Sub && (returnTypeToken === undefined || (returnTypeToken === null || returnTypeToken === void 0 ? void 0 : returnTypeToken.kind) === brighterscript_1.TokenKind.Void)) || (returnTypeToken === null || returnTypeToken === void 0 ? void 0 : returnTypeToken.kind) === brighterscript_1.TokenKind.Void); } exports.functionRequiresReturnValue = functionRequiresReturnValue; function getAllDottedGetParts(dg) { var _a, _b; let parts = [(_a = dg === null || dg === void 0 ? void 0 : dg.name) === null || _a === void 0 ? void 0 : _a.text]; let nextPart = dg.obj; while ((0, brighterscript_1.isDottedGetExpression)(nextPart) || (0, brighterscript_1.isVariableExpression)(nextPart)) { parts.push((_b = nextPart === null || nextPart === void 0 ? void 0 : nextPart.name) === null || _b === void 0 ? void 0 : _b.text); nextPart = (0, brighterscript_1.isDottedGetExpression)(nextPart) ? nextPart.obj : undefined; } return parts.reverse(); } exports.getAllDottedGetParts = getAllDottedGetParts; function getRootObjectFromDottedGet(value) { let root; if ((0, brighterscript_1.isDottedGetExpression)(value) || (0, brighterscript_1.isIndexedGetExpression)(value)) { root = value.obj; while (root.obj) { root = root.obj; } } else { root = value; } return root; } exports.getRootObjectFromDottedGet = getRootObjectFromDottedGet; function getStringPathFromDottedGet(value) { let parts = [getPathValuePartAsString(value)]; let root; root = value.obj; while (root) { if ((0, brighterscript_1.isCallExpression)(root) || (0, brighterscript_1.isCallfuncExpression)(root)) { return undefined; } parts.push(`${getPathValuePartAsString(root)}`); root = root.obj; } let joinedParts = parts.reverse().join('.'); return joinedParts === '' ? undefined : (0, brighterscript_1.createStringLiteral)(joinedParts); } exports.getStringPathFromDottedGet = getStringPathFromDottedGet; function getPathValuePartAsString(expr) { if ((0, brighterscript_1.isCallExpression)(expr) || (0, brighterscript_1.isCallfuncExpression)(expr)) { return undefined; } if ((0, brighterscript_1.isVariableExpression)(expr)) { return expr.name.text; } if (!expr) { return undefined; } if ((0, brighterscript_1.isDottedGetExpression)(expr)) { return expr.name.text; } else if ((0, brighterscript_1.isIndexedGetExpression)(expr)) { if ((0, brighterscript_1.isLiteralExpression)(expr.index)) { return `${expr.index.token.text.replace(/^"/, '').replace(/"$/, '')}`; } else if ((0, brighterscript_1.isVariableExpression)(expr.index)) { return `${expr.index.name.text}`; } } } exports.getPathValuePartAsString = getPathValuePartAsString; function getScopeForSuite(testSuite) { if (testSuite.isNodeTest) { return testSuite.file.program.getScopesForFile(testSuite.file).find((scope) => { return (0, brighterscript_1.isXmlScope)(scope) && scope.xmlFile.componentName.text === testSuite.generatedNodeName; }); } else { return testSuite.file.program.getFirstScopeForFile(testSuite.file); } } exports.getScopeForSuite = getScopeForSuite; //# sourceMappingURL=Utils.js.map