@flamework-experimental/transformer 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +66 -0
  2. package/flamework-schema.json +76 -0
  3. package/flamework.config.schema.json +197 -0
  4. package/out/classes/buildInfo.js +467 -0
  5. package/out/classes/diagnostics.js +110 -0
  6. package/out/classes/logger.js +201 -0
  7. package/out/classes/nodeMetadata.js +232 -0
  8. package/out/classes/transformState.js +623 -0
  9. package/out/index.js +75 -0
  10. package/out/transformations/expressions/transformAccessExpression.js +35 -0
  11. package/out/transformations/expressions/transformBinaryExpression.js +57 -0
  12. package/out/transformations/expressions/transformCallExpression.js +33 -0
  13. package/out/transformations/expressions/transformDeleteExpression.js +22 -0
  14. package/out/transformations/expressions/transformNewExpression.js +17 -0
  15. package/out/transformations/expressions/transformUnaryExpression.js +63 -0
  16. package/out/transformations/macros/intrinsics/components.js +64 -0
  17. package/out/transformations/macros/intrinsics/env.js +31 -0
  18. package/out/transformations/macros/intrinsics/guards.js +43 -0
  19. package/out/transformations/macros/intrinsics/inlining.js +22 -0
  20. package/out/transformations/macros/intrinsics/networking.js +131 -0
  21. package/out/transformations/macros/intrinsics/parameters.js +81 -0
  22. package/out/transformations/macros/intrinsics/paths.js +42 -0
  23. package/out/transformations/macros/updateComponentConfig.js +409 -0
  24. package/out/transformations/plugins/nodeFactory.js +159 -0
  25. package/out/transformations/plugins/pluginHost.js +235 -0
  26. package/out/transformations/plugins/typeFacade.js +242 -0
  27. package/out/transformations/statements/transformClassDeclaration.js +282 -0
  28. package/out/transformations/transformExpression.js +34 -0
  29. package/out/transformations/transformFile.js +78 -0
  30. package/out/transformations/transformNetworkingCall.js +566 -0
  31. package/out/transformations/transformNode.js +27 -0
  32. package/out/transformations/transformStatement.js +57 -0
  33. package/out/transformations/transformStatementList.js +64 -0
  34. package/out/transformations/transformUserMacro.js +698 -0
  35. package/out/transformer.js +52 -0
  36. package/out/util/cache.js +10 -0
  37. package/out/util/constants.js +5 -0
  38. package/out/util/diagnosticsUtils.js +112 -0
  39. package/out/util/env.js +267 -0
  40. package/out/util/factory.js +583 -0
  41. package/out/util/functions/addLeadingComment.js +13 -0
  42. package/out/util/functions/arePathsEqual.js +14 -0
  43. package/out/util/functions/assert.js +17 -0
  44. package/out/util/functions/buildGuardFromType.js +713 -0
  45. package/out/util/functions/buildInstanceShape.js +156 -0
  46. package/out/util/functions/buildSerializerFromType.js +2309 -0
  47. package/out/util/functions/createPathTranslator.js +54 -0
  48. package/out/util/functions/emitTypescriptMismatch.js +80 -0
  49. package/out/util/functions/getDeclarationName.js +23 -0
  50. package/out/util/functions/getDeclarationOfType.js +7 -0
  51. package/out/util/functions/getIndexExpression.js +16 -0
  52. package/out/util/functions/getInstanceTypeFromType.js +75 -0
  53. package/out/util/functions/getNodeList.js +6 -0
  54. package/out/util/functions/getPackageJson.js +44 -0
  55. package/out/util/functions/getSuperClasses.js +51 -0
  56. package/out/util/functions/isAttributesAccess.js +23 -0
  57. package/out/util/functions/isCleanBuildDirectory.js +13 -0
  58. package/out/util/functions/isDefinedType.js +16 -0
  59. package/out/util/functions/isPathDescendantOf.js +25 -0
  60. package/out/util/functions/isTupleType.js +10 -0
  61. package/out/util/functions/parseCommandLine.js +31 -0
  62. package/out/util/functions/shuffle.js +39 -0
  63. package/out/util/functions/tryResolve.js +15 -0
  64. package/out/util/functions/validateConstraintMetadata.js +60 -0
  65. package/out/util/packages.js +12 -0
  66. package/out/util/projectConfig.js +221 -0
  67. package/out/util/schema.js +80 -0
  68. package/out/util/tsInternals.js +16 -0
  69. package/out/util/uid.js +227 -0
  70. package/package.json +45 -0
  71. package/rojo-schema.json +34 -0
  72. package/types.d.ts +4 -0
package/out/index.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ /* eslint-disable @typescript-eslint/no-require-imports */
6
+ var fs_1 = require("fs");
7
+ var module_1 = require("module");
8
+ var path_1 = __importDefault(require("path"));
9
+ var isPathDescendantOf_1 = require("./util/functions/isPathDescendantOf");
10
+ var logger_1 = require("./classes/logger");
11
+ function resolve(moduleName, path) {
12
+ try {
13
+ return require.resolve(moduleName, { paths: [path] });
14
+ }
15
+ finally {
16
+ }
17
+ }
18
+ var cwd = process.cwd();
19
+ var originalRequire = module_1.Module.prototype.require;
20
+ function shouldTryHooking() {
21
+ if (process.argv.includes("--no-flamework-hook")) {
22
+ return false;
23
+ }
24
+ if (process.argv.includes("--force-flamework-hook")) {
25
+ return true;
26
+ }
27
+ // Ensure we're running in the context of a project and not a multiplace repository or something,
28
+ // as we don't have access to the project directory until roblox-ts invokes the transformer.
29
+ //
30
+ // A node_modules folder is deliberately not required: a package inside a workspace with hoisted
31
+ // dependencies has none of its own, and resolving roblox-ts from here (see hook) already tells us
32
+ // whether there is an install to switch to.
33
+ if (!(0, fs_1.existsSync)(path_1.default.join(cwd, "tsconfig.json")) || !(0, fs_1.existsSync)(path_1.default.join(cwd, "package.json"))) {
34
+ return false;
35
+ }
36
+ return true;
37
+ }
38
+ function hook() {
39
+ var robloxTsPath = resolve("roblox-ts", cwd);
40
+ if (!robloxTsPath) {
41
+ return;
42
+ }
43
+ var robloxTsTypeScriptPath = resolve("typescript", robloxTsPath);
44
+ if (!robloxTsTypeScriptPath) {
45
+ return;
46
+ }
47
+ var flameworkTypeScript = require("typescript");
48
+ var robloxTsTypeScript = require(robloxTsTypeScriptPath);
49
+ // Flamework and roblox-ts are referencing the same TypeScript module.
50
+ if (flameworkTypeScript === robloxTsTypeScript) {
51
+ return;
52
+ }
53
+ if (flameworkTypeScript.versionMajorMinor !== robloxTsTypeScript.versionMajorMinor) {
54
+ if (logger_1.Logger.verbose) {
55
+ logger_1.Logger.write("\n");
56
+ }
57
+ logger_1.Logger.warn("TypeScript version differs", "Flamework: v".concat(flameworkTypeScript.version, ", roblox-ts: v").concat(robloxTsTypeScript.version), "Flamework will switch to v".concat(robloxTsTypeScript.version, ", ") +
58
+ "but you can get rid of this warning by running: npm i -D typescript@".concat(robloxTsTypeScript.version));
59
+ }
60
+ module_1.Module.prototype.require = function flameworkHook(id) {
61
+ // Overwrite any Flamework TypeScript imports to roblox-ts' version.
62
+ // To be on the safe side, this won't hook it in packages.
63
+ if (id === "typescript" && (0, isPathDescendantOf_1.isPathDescendantOf)(this.filename, __dirname)) {
64
+ return robloxTsTypeScript;
65
+ }
66
+ return originalRequire.call(this, id);
67
+ };
68
+ }
69
+ if (shouldTryHooking()) {
70
+ hook();
71
+ }
72
+ var transformer = require("./transformer");
73
+ // After loading Flamework, we can unhook require.
74
+ module_1.Module.prototype.require = originalRequire;
75
+ module.exports = transformer;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformAccessExpression = transformAccessExpression;
4
+ var factory_1 = require("../../util/factory");
5
+ var diagnostics_1 = require("../../classes/diagnostics");
6
+ function transformAccessExpression(state, node) {
7
+ var _a;
8
+ return (_a = transformNetworkEvent(state, node)) !== null && _a !== void 0 ? _a : state.transform(node);
9
+ }
10
+ function transformNetworkEvent(state, node) {
11
+ var type = state.typeChecker.getTypeAtLocation(node.expression);
12
+ var hashType = state.typeChecker.getTypeOfPropertyOfType(type, "_flamework_key_obfuscation");
13
+ if (!hashType || !hashType.isStringLiteral())
14
+ return;
15
+ // If the access expression doesn't have a name known at compile-time, we must throw an error.
16
+ var name = getAccessName(node);
17
+ if (name === undefined) {
18
+ // This is prevents compiler errors when we're defining obfuscated objects, or accessing them internally.
19
+ if (factory_1.f.is.elementAccessExpression(node) && factory_1.f.is.asExpression(node.argumentExpression)) {
20
+ return;
21
+ }
22
+ diagnostics_1.Diagnostics.error(node, "This object has key obfuscation enabled and must be accessed directly.");
23
+ }
24
+ return factory_1.f.elementAccessExpression(state.transformNode(node.expression), factory_1.f.as(factory_1.f.string(state.obfuscateText(name, hashType.value)), factory_1.f.literalType(factory_1.f.string(name))), node.questionDotToken);
25
+ }
26
+ function getAccessName(node) {
27
+ if (factory_1.f.is.propertyAccessExpression(node)) {
28
+ return node.name.text;
29
+ }
30
+ else {
31
+ if (factory_1.f.is.string(node.argumentExpression)) {
32
+ return node.argumentExpression.text;
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.transformBinaryExpression = transformBinaryExpression;
7
+ var typescript_1 = __importDefault(require("typescript"));
8
+ var diagnostics_1 = require("../../classes/diagnostics");
9
+ var factory_1 = require("../../util/factory");
10
+ var getIndexExpression_1 = require("../../util/functions/getIndexExpression");
11
+ var isAttributesAccess_1 = require("../../util/functions/isAttributesAccess");
12
+ var packages_1 = require("../../util/packages");
13
+ var MUTATING_OPERATORS = new Map([
14
+ [typescript_1.default.SyntaxKind.EqualsToken, typescript_1.default.SyntaxKind.EqualsToken],
15
+ [typescript_1.default.SyntaxKind.BarEqualsToken, typescript_1.default.SyntaxKind.BarToken],
16
+ [typescript_1.default.SyntaxKind.PlusEqualsToken, typescript_1.default.SyntaxKind.PlusToken],
17
+ [typescript_1.default.SyntaxKind.MinusEqualsToken, typescript_1.default.SyntaxKind.MinusToken],
18
+ [typescript_1.default.SyntaxKind.CaretEqualsToken, typescript_1.default.SyntaxKind.CaretToken],
19
+ [typescript_1.default.SyntaxKind.SlashEqualsToken, typescript_1.default.SyntaxKind.SlashToken],
20
+ [typescript_1.default.SyntaxKind.BarBarEqualsToken, typescript_1.default.SyntaxKind.BarBarToken],
21
+ [typescript_1.default.SyntaxKind.PercentEqualsToken, typescript_1.default.SyntaxKind.PercentToken],
22
+ [typescript_1.default.SyntaxKind.AsteriskEqualsToken, typescript_1.default.SyntaxKind.AsteriskToken],
23
+ [typescript_1.default.SyntaxKind.AmpersandEqualsToken, typescript_1.default.SyntaxKind.AmpersandToken],
24
+ [typescript_1.default.SyntaxKind.QuestionQuestionEqualsToken, typescript_1.default.SyntaxKind.QuestionQuestionToken],
25
+ [typescript_1.default.SyntaxKind.AsteriskAsteriskEqualsToken, typescript_1.default.SyntaxKind.AsteriskAsteriskToken],
26
+ [typescript_1.default.SyntaxKind.LessThanLessThanEqualsToken, typescript_1.default.SyntaxKind.LessThanLessThanToken],
27
+ [typescript_1.default.SyntaxKind.AmpersandAmpersandEqualsToken, typescript_1.default.SyntaxKind.AmpersandAmpersandToken],
28
+ [typescript_1.default.SyntaxKind.GreaterThanGreaterThanEqualsToken, typescript_1.default.SyntaxKind.GreaterThanGreaterThanToken],
29
+ [typescript_1.default.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, typescript_1.default.SyntaxKind.GreaterThanGreaterThanGreaterThanToken],
30
+ ]);
31
+ /**
32
+ * Writes to `this.attributes` go through the component, which writes the value back to the
33
+ * instance. `attributes` is an ordinary field otherwise, so the rewrite is what makes assignment
34
+ * mean anything at all.
35
+ */
36
+ function transformBinaryExpression(state, node) {
37
+ var nonAssignmentOperator = MUTATING_OPERATORS.get(node.operatorToken.kind);
38
+ if (nonAssignmentOperator) {
39
+ if ((0, isAttributesAccess_1.isAttributesAccess)(state, node.left)) {
40
+ var name_1 = (0, getIndexExpression_1.getIndexExpression)(node.left);
41
+ if (!name_1)
42
+ diagnostics_1.Diagnostics.error(node.left, "could not get index expression");
43
+ if (!factory_1.f.is.accessExpression(node.left.expression))
44
+ diagnostics_1.Diagnostics.error(node.left, "assignments not supported with direct access");
45
+ var attributeSetter = state.addFileImport(node.getSourceFile(), "".concat(packages_1.COMPONENTS_PACKAGE, "/out/baseComponent"), "SYMBOL_ATTRIBUTE_SETTER");
46
+ var thisAccess = node.left.expression.expression;
47
+ var valueExpr = nonAssignmentOperator === typescript_1.default.SyntaxKind.EqualsToken
48
+ ? node.right
49
+ : factory_1.f.binary(node.left, nonAssignmentOperator, node.right);
50
+ return factory_1.f.call(factory_1.f.field(state.transformNode(thisAccess), attributeSetter, true), [
51
+ name_1,
52
+ state.transformNode(valueExpr),
53
+ ]);
54
+ }
55
+ }
56
+ return state.transform(node);
57
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.transformCallExpression = transformCallExpression;
7
+ var typescript_1 = __importDefault(require("typescript"));
8
+ var transformNode_1 = require("../transformNode");
9
+ var transformUserMacro_1 = require("../transformUserMacro");
10
+ var factory_1 = require("../../util/factory");
11
+ var transformNetworkingCall_1 = require("../transformNetworkingCall");
12
+ function transformCallExpression(state, node) {
13
+ var _a;
14
+ var symbol = state.getSymbol(node.expression);
15
+ if (symbol) {
16
+ if (state.isUserMacro(symbol)) {
17
+ // We skip `super()` expressions as we likely do not have enough information to evaluate it.
18
+ if (factory_1.f.is.superExpression(node.expression)) {
19
+ return state.transform(node);
20
+ }
21
+ var signature = state.typeChecker.getResolvedSignature(node);
22
+ if (signature) {
23
+ return (_a = (0, transformUserMacro_1.transformUserMacro)(state, node, signature)) !== null && _a !== void 0 ? _a : state.transform(node);
24
+ }
25
+ }
26
+ }
27
+ // With networking serialization on, sends and function callbacks pack their values right here.
28
+ var networking = (0, transformNetworkingCall_1.transformNetworkingCall)(state, node);
29
+ if (networking) {
30
+ return networking;
31
+ }
32
+ return typescript_1.default.visitEachChild(node, function (node) { return (0, transformNode_1.transformNode)(state, node); }, state.context);
33
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformDeleteExpression = transformDeleteExpression;
4
+ var diagnostics_1 = require("../../classes/diagnostics");
5
+ var factory_1 = require("../../util/factory");
6
+ var getIndexExpression_1 = require("../../util/functions/getIndexExpression");
7
+ var isAttributesAccess_1 = require("../../util/functions/isAttributesAccess");
8
+ var packages_1 = require("../../util/packages");
9
+ /** `delete this.attributes.label` clears the attribute on the instance. */
10
+ function transformDeleteExpression(state, node) {
11
+ if ((0, isAttributesAccess_1.isAttributesAccess)(state, node.expression)) {
12
+ var name_1 = (0, getIndexExpression_1.getIndexExpression)(node.expression);
13
+ if (!name_1)
14
+ diagnostics_1.Diagnostics.error(node.expression, "could not get index expression");
15
+ if (!factory_1.f.is.accessExpression(node.expression.expression))
16
+ diagnostics_1.Diagnostics.error(node.expression, "assignments not supported with direct access");
17
+ var attributeSetter = state.addFileImport(node.getSourceFile(), "".concat(packages_1.COMPONENTS_PACKAGE, "/out/baseComponent"), "SYMBOL_ATTRIBUTE_SETTER");
18
+ var thisAccess = node.expression.expression.expression;
19
+ return factory_1.f.call(factory_1.f.field(state.transformNode(thisAccess), attributeSetter, true), [name_1, factory_1.f.nil()]);
20
+ }
21
+ return state.transform(node);
22
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformNewExpression = transformNewExpression;
4
+ var transformUserMacro_1 = require("../transformUserMacro");
5
+ function transformNewExpression(state, node) {
6
+ var _a;
7
+ var symbol = state.getSymbol(node.expression);
8
+ if (symbol) {
9
+ if (state.isUserMacro(symbol)) {
10
+ var signature = state.typeChecker.getResolvedSignature(node);
11
+ if (signature) {
12
+ return (_a = (0, transformUserMacro_1.transformUserMacro)(state, node, signature)) !== null && _a !== void 0 ? _a : state.transform(node);
13
+ }
14
+ }
15
+ }
16
+ return state.transform(node);
17
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __read = (this && this.__read) || function (o, n) {
3
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
4
+ if (!m) return o;
5
+ var i = m.call(o), r, ar = [], e;
6
+ try {
7
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
+ }
9
+ catch (error) { e = { error: error }; }
10
+ finally {
11
+ try {
12
+ if (r && !r.done && (m = i["return"])) m.call(i);
13
+ }
14
+ finally { if (e) throw e.error; }
15
+ }
16
+ return ar;
17
+ };
18
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
+ if (ar || !(i in from)) {
21
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
+ ar[i] = from[i];
23
+ }
24
+ }
25
+ return to.concat(ar || Array.prototype.slice.call(from));
26
+ };
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.transformUnaryExpression = transformUnaryExpression;
32
+ var typescript_1 = __importDefault(require("typescript"));
33
+ var diagnostics_1 = require("../../classes/diagnostics");
34
+ var factory_1 = require("../../util/factory");
35
+ var getIndexExpression_1 = require("../../util/functions/getIndexExpression");
36
+ var isAttributesAccess_1 = require("../../util/functions/isAttributesAccess");
37
+ var packages_1 = require("../../util/packages");
38
+ var MUTATING_OPERATORS = new Map([
39
+ [typescript_1.default.SyntaxKind.PlusPlusToken, typescript_1.default.SyntaxKind.PlusToken],
40
+ [typescript_1.default.SyntaxKind.MinusMinusToken, typescript_1.default.SyntaxKind.MinusToken],
41
+ ]);
42
+ /** `this.attributes.count++`, which is the same write as `count += 1`. */
43
+ function transformUnaryExpression(state, node) {
44
+ var nonAssignmentOperator = MUTATING_OPERATORS.get(node.operator);
45
+ if (nonAssignmentOperator) {
46
+ if ((0, isAttributesAccess_1.isAttributesAccess)(state, node.operand)) {
47
+ var name_1 = (0, getIndexExpression_1.getIndexExpression)(node.operand);
48
+ if (!name_1)
49
+ diagnostics_1.Diagnostics.error(node.operand, "could not get index expression");
50
+ if (!factory_1.f.is.accessExpression(node.operand.expression))
51
+ diagnostics_1.Diagnostics.error(node.operand, "assignments not supported with direct access");
52
+ var attributeSetter = state.addFileImport(node.getSourceFile(), "".concat(packages_1.COMPONENTS_PACKAGE, "/out/baseComponent"), "SYMBOL_ATTRIBUTE_SETTER");
53
+ var thisAccess = node.operand.expression.expression;
54
+ // The value is transformed rather than handed over as written: the operand carries the
55
+ // receiver a second time, and a receiver can be a macro call whose id this very pass is
56
+ // what injects. Leaving it alone emits the call without its id, which then fails to
57
+ // resolve at runtime.
58
+ var args = [name_1, state.transformNode(factory_1.f.binary(node.operand, nonAssignmentOperator, 1))];
59
+ return factory_1.f.call(factory_1.f.field(state.transformNode(thisAccess), attributeSetter, true), factory_1.f.is.postfixUnary(node) ? __spreadArray(__spreadArray([], __read(args), false), [true], false) : args);
60
+ }
61
+ }
62
+ return state.transform(node);
63
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __read = (this && this.__read) || function (o, n) {
3
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
4
+ if (!m) return o;
5
+ var i = m.call(o), r, ar = [], e;
6
+ try {
7
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
+ }
9
+ catch (error) { e = { error: error }; }
10
+ finally {
11
+ try {
12
+ if (r && !r.done && (m = i["return"])) m.call(i);
13
+ }
14
+ finally { if (e) throw e.error; }
15
+ }
16
+ return ar;
17
+ };
18
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
+ if (ar || !(i in from)) {
21
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
+ ar[i] = from[i];
23
+ }
24
+ }
25
+ return to.concat(ar || Array.prototype.slice.call(from));
26
+ };
27
+ var __values = (this && this.__values) || function(o) {
28
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
29
+ if (m) return m.call(o);
30
+ if (o && typeof o.length === "number") return {
31
+ next: function () {
32
+ if (o && i >= o.length) o = void 0;
33
+ return { value: o && o[i++], done: !o };
34
+ }
35
+ };
36
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.transformComponentConfig = transformComponentConfig;
40
+ var factory_1 = require("../../../util/factory");
41
+ var updateComponentConfig_1 = require("../updateComponentConfig");
42
+ function transformComponentConfig(state, declaration, signature, parameters, args) {
43
+ var e_1, _a;
44
+ var _loop_1 = function (parameter) {
45
+ var parameterIndex = signature.parameters.findIndex(function (v) { var _a; return ((_a = v.valueDeclaration) === null || _a === void 0 ? void 0 : _a.symbol) === parameter; });
46
+ var argument = args[parameterIndex];
47
+ var baseConfig = factory_1.f.is.object(argument) ? argument : factory_1.f.object([]);
48
+ var componentConfig = (0, updateComponentConfig_1.updateComponentConfig)(state, declaration, __spreadArray([], __read(baseConfig.properties), false));
49
+ args[parameterIndex] = factory_1.f.update.object(baseConfig, componentConfig.map(function (v) { return (baseConfig.properties.includes(v) ? state.transformNode(v) : v); }));
50
+ };
51
+ try {
52
+ for (var parameters_1 = __values(parameters), parameters_1_1 = parameters_1.next(); !parameters_1_1.done; parameters_1_1 = parameters_1.next()) {
53
+ var parameter = parameters_1_1.value;
54
+ _loop_1(parameter);
55
+ }
56
+ }
57
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
58
+ finally {
59
+ try {
60
+ if (parameters_1_1 && !parameters_1_1.done && (_a = parameters_1.return)) _a.call(parameters_1);
61
+ }
62
+ finally { if (e_1) throw e_1.error; }
63
+ }
64
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildEnvIntrinsic = buildEnvIntrinsic;
7
+ var typescript_1 = __importDefault(require("typescript"));
8
+ var diagnostics_1 = require("../../../classes/diagnostics");
9
+ var factory_1 = require("../../../util/factory");
10
+ /**
11
+ * Inlines an environment variable: `Flamework.env("NAME")` becomes the variable's value as a
12
+ * string literal, from the environment the compiler read when it started (`.env`, `.env.local`,
13
+ * the process), or `nil` when it is not set. A fallback is inlined in its place, and has to be a
14
+ * string literal: it is what lets the declared type promise a `string`, so one the compiler cannot
15
+ * read is refused rather than quietly dropped.
16
+ */
17
+ function buildEnvIntrinsic(state, node, nameType, fallbackType) {
18
+ var _a;
19
+ if (!nameType.isStringLiteral()) {
20
+ diagnostics_1.Diagnostics.error(node, "Flamework.env expects the variable's name as a string literal, got: ".concat(state.typeChecker.typeToString(nameType)));
21
+ }
22
+ var fallback;
23
+ if (fallbackType !== undefined && (fallbackType.flags & typescript_1.default.TypeFlags.Undefined) === 0) {
24
+ if (!fallbackType.isStringLiteral()) {
25
+ diagnostics_1.Diagnostics.error(node, "Flamework.env expects the fallback as a string literal, got: ".concat(state.typeChecker.typeToString(fallbackType)), "The fallback is inlined at compile time, which is what makes the result a string rather than string | undefined.");
26
+ }
27
+ fallback = fallbackType.value;
28
+ }
29
+ var value = (_a = state.env[nameType.value]) !== null && _a !== void 0 ? _a : fallback;
30
+ return value === undefined ? factory_1.f.nil() : factory_1.f.string(value);
31
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildTupleGuardsIntrinsic = buildTupleGuardsIntrinsic;
7
+ var typescript_1 = __importDefault(require("typescript"));
8
+ var diagnostics_1 = require("../../../classes/diagnostics");
9
+ var factory_1 = require("../../../util/factory");
10
+ var buildGuardFromType_1 = require("../../../util/functions/buildGuardFromType");
11
+ var isTupleType_1 = require("../../../util/functions/isTupleType");
12
+ /**
13
+ * This intrinsic generates an array of element guards along with a rest guard for a tuple type.
14
+ *
15
+ * Whilst this is possible in TypeScript, it requires either slightly complex types or additional metadata.
16
+ * This serves as a simple fast path.
17
+ */
18
+ function buildTupleGuardsIntrinsic(state, node, tupleType) {
19
+ var _a;
20
+ var file = state.getSourceFile(node);
21
+ // Tuples with only a rest element will get turned into an array
22
+ if ((0, isTupleType_1.isArrayType)(state, tupleType)) {
23
+ var guard = (0, buildGuardFromType_1.buildGuardFromType)(state, node, tupleType.typeArguments[0], file);
24
+ return factory_1.f.array([factory_1.f.array([]), guard]);
25
+ }
26
+ if (!(0, isTupleType_1.isTupleType)(state, tupleType) || !tupleType.typeArguments) {
27
+ diagnostics_1.Diagnostics.error(node, "Intrinsic encountered non-tuple type: ".concat(state.typeChecker.typeToString(tupleType)));
28
+ }
29
+ var guards = new Array();
30
+ var restGuard = factory_1.f.nil();
31
+ for (var i = 0; i < tupleType.typeArguments.length; i++) {
32
+ var element = tupleType.typeArguments[i];
33
+ var declaration = (_a = tupleType.target.labeledElementDeclarations) === null || _a === void 0 ? void 0 : _a[i];
34
+ var guard = (0, buildGuardFromType_1.buildGuardFromType)(state, declaration !== null && declaration !== void 0 ? declaration : node, element, file);
35
+ if (tupleType.target.elementFlags[i] & typescript_1.default.ElementFlags.Rest) {
36
+ restGuard = guard;
37
+ }
38
+ else {
39
+ guards.push(guard);
40
+ }
41
+ }
42
+ return factory_1.f.array([factory_1.f.array(guards), restGuard]);
43
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.inlineMacroIntrinsic = inlineMacroIntrinsic;
7
+ var typescript_1 = __importDefault(require("typescript"));
8
+ var factory_1 = require("../../../util/factory");
9
+ /**
10
+ * An inlining intrinsic: the call is replaced by the value generated for one of its parameters.
11
+ *
12
+ * The value is cast to the call's resolved return type rather than to the declaration's return
13
+ * type node: a declaration such as `F extends string ? string : string | undefined` names type
14
+ * parameters that mean nothing in the caller's file, whereas the resolved type of that call is a
15
+ * plain `string | undefined` the checker can write down there.
16
+ */
17
+ function inlineMacroIntrinsic(state, node, signature, args, parameter) {
18
+ var parameterIndex = signature.parameters.findIndex(function (v) { var _a; return ((_a = v.valueDeclaration) === null || _a === void 0 ? void 0 : _a.symbol) === parameter; });
19
+ var argument = args[parameterIndex];
20
+ var returnType = state.typeChecker.typeToTypeNode(signature.getReturnType(), node, typescript_1.default.NodeBuilderFlags.NoTruncation);
21
+ return returnType !== undefined ? factory_1.f.as(argument, returnType) : argument;
22
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __values = (this && this.__values) || function(o) {
3
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
4
+ if (m) return m.call(o);
5
+ if (o && typeof o.length === "number") return {
6
+ next: function () {
7
+ if (o && i >= o.length) o = void 0;
8
+ return { value: o && o[i++], done: !o };
9
+ }
10
+ };
11
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
12
+ };
13
+ var __read = (this && this.__read) || function (o, n) {
14
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
15
+ if (!m) return o;
16
+ var i = m.call(o), r, ar = [], e;
17
+ try {
18
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
19
+ }
20
+ catch (error) { e = { error: error }; }
21
+ finally {
22
+ try {
23
+ if (r && !r.done && (m = i["return"])) m.call(i);
24
+ }
25
+ finally { if (e) throw e.error; }
26
+ }
27
+ return ar;
28
+ };
29
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
30
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
31
+ if (ar || !(i in from)) {
32
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
33
+ ar[i] = from[i];
34
+ }
35
+ }
36
+ return to.concat(ar || Array.prototype.slice.call(from));
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.transformNetworkingMiddlewareIntrinsic = transformNetworkingMiddlewareIntrinsic;
43
+ exports.transformObfuscatedObjectIntrinsic = transformObfuscatedObjectIntrinsic;
44
+ exports.transformShuffleArrayIntrinsic = transformShuffleArrayIntrinsic;
45
+ var typescript_1 = __importDefault(require("typescript"));
46
+ var assert_1 = __importDefault(require("assert"));
47
+ var factory_1 = require("../../../util/factory");
48
+ var diagnostics_1 = require("../../../classes/diagnostics");
49
+ /**
50
+ * Obfuscates the names of events provided in networking middleware.
51
+ *
52
+ * This should eventually be replaced with a generic object obfuscation API.
53
+ */
54
+ function transformNetworkingMiddlewareIntrinsic(state, signature, args, parameters) {
55
+ var e_1, _a;
56
+ var _loop_1 = function (parameter) {
57
+ var parameterIndex = signature.parameters.findIndex(function (v) { var _a; return ((_a = v.valueDeclaration) === null || _a === void 0 ? void 0 : _a.symbol) === parameter; });
58
+ var argument = args[parameterIndex];
59
+ if (!argument || !typescript_1.default.isObjectLiteralExpression(argument)) {
60
+ return "continue";
61
+ }
62
+ var obfuscateMiddleware = function (middlewareObject) {
63
+ return factory_1.f.update.object(middlewareObject, state.obfuscateArray(middlewareObject.properties).map(function (prop) {
64
+ if (factory_1.f.is.propertyAssignmentDeclaration(prop) && "text" in prop.name) {
65
+ return factory_1.f.update.propertyAssignmentDeclaration(prop, factory_1.f.is.object(prop.initializer) ? obfuscateMiddleware(prop.initializer) : prop.initializer, factory_1.f.computedPropertyName(factory_1.f.as(factory_1.f.string(state.obfuscateText(prop.name.text, "remotes")), factory_1.f.literalType(factory_1.f.string(prop.name.text)))));
66
+ }
67
+ return prop;
68
+ }));
69
+ };
70
+ var transformedElements = argument.properties.map(function (element) {
71
+ var name = element.name && typescript_1.default.getPropertyNameForPropertyNameNode(element.name);
72
+ if (name !== "middleware") {
73
+ return element;
74
+ }
75
+ (0, assert_1.default)(factory_1.f.is.propertyAssignmentDeclaration(element));
76
+ var value = element.initializer;
77
+ if (!factory_1.f.is.object(value)) {
78
+ diagnostics_1.Diagnostics.error(value, "Networking middleware must be an object.");
79
+ }
80
+ return factory_1.f.update.propertyAssignmentDeclaration(element, obfuscateMiddleware(value));
81
+ });
82
+ args[parameterIndex] = factory_1.f.object(transformedElements, true);
83
+ };
84
+ try {
85
+ for (var parameters_1 = __values(parameters), parameters_1_1 = parameters_1.next(); !parameters_1_1.done; parameters_1_1 = parameters_1.next()) {
86
+ var parameter = parameters_1_1.value;
87
+ _loop_1(parameter);
88
+ }
89
+ }
90
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
91
+ finally {
92
+ try {
93
+ if (parameters_1_1 && !parameters_1_1.done && (_a = parameters_1.return)) _a.call(parameters_1);
94
+ }
95
+ finally { if (e_1) throw e_1.error; }
96
+ }
97
+ }
98
+ /**
99
+ * Obfuscates the keys of user macro metadata using the specified context.
100
+ *
101
+ * This should eventually be replaced with a generic object obfuscation API.
102
+ */
103
+ function transformObfuscatedObjectIntrinsic(state, macro, hashType) {
104
+ var e_2, _a;
105
+ var hashContext = hashType.isStringLiteral() ? hashType.value : undefined;
106
+ if (macro.kind === "many" && macro.members instanceof Map) {
107
+ try {
108
+ // Maps are order-preserving, so we can shuffle the map directly.
109
+ for (var _b = __values(state.obfuscateArray(__spreadArray([], __read(macro.members), false))), _c = _b.next(); !_c.done; _c = _b.next()) {
110
+ var _d = __read(_c.value, 2), key = _d[0], inner = _d[1];
111
+ macro.members.delete(key);
112
+ macro.members.set(state.obfuscateText(key, hashContext), inner);
113
+ }
114
+ }
115
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
116
+ finally {
117
+ try {
118
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
119
+ }
120
+ finally { if (e_2) throw e_2.error; }
121
+ }
122
+ }
123
+ }
124
+ /**
125
+ * Shuffles the order of an array to prevent const-matching.
126
+ */
127
+ function transformShuffleArrayIntrinsic(state, macro) {
128
+ if (macro.kind === "many" && Array.isArray(macro.members)) {
129
+ macro.members = state.obfuscateArray(macro.members);
130
+ }
131
+ }