Socket
Socket
Sign inDemoInstall

typescript-to-lua

Package Overview
Dependencies
Maintainers
2
Versions
157
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-to-lua - npm Package Compare versions

Comparing version 0.35.0 to 0.36.0

dist/lualib/CloneDescriptor.lua

14

CHANGELOG.md
# Changelog
## Unreleased
## 0.35.0
- `Function.length` is supported now
- In preparation for some new features, some public APIs have been changed:
- High-level APIs that read input files from the file system (`transpileFiles` and `transpileProject`) now write transpiled files by default. This behavior can be changed by providing a `writeFile` callback, similarly to TypeScript's `program.emit`.
- `transpile` and `emitTranspiledFiles` functions have been replaced with the `Transpiler` class. See [documentation](https://typescripttolua.github.io/docs/api/overview#low-level-api) for usage examples.
- Fixed `declarationDir` option not being respected.
- `Function.length` is supported now.
- String iteration is now supported.
- Exposed `parseConfigFileWithSystem` to parse _tsconfig.json_ files as part of the tstl API.
- Fixed `string.replace` incorrectly escaping some `replaceValue` characters (`().+-*?[^$`)
- Fixed several other string operations behaving differently from JS (mostly regarding indices out of bounds and NaN arguments).
- Fixed a bug where the length argument of `String.prototype.substr` was evaluated twice.
- Fixed some missing dependencies in LuaLib classes (Map, Set, WeakMap, WeakSet)

@@ -9,0 +17,0 @@ ## 0.34.0

@@ -5,2 +5,3 @@ import * as ts from "typescript";

reportsUnnecessary?: {} | undefined;
reportsDeprecated?: {} | undefined;
source?: string | undefined;

@@ -7,0 +8,0 @@ relatedInformation?: ts.DiagnosticRelatedInformation[] | undefined;

@@ -10,5 +10,6 @@ "use strict";

var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
}
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LuaLibFeature = exports.parseConfigFileWithSystem = exports.updateParsedConfigFile = exports.parseCommandLine = exports.version = void 0;
var information_1 = require("./cli/information");

@@ -15,0 +16,0 @@ Object.defineProperty(exports, "version", { enumerable: true, get: function () { return information_1.version; } });

import * as ts from "typescript";
import { LuaLibFeature } from "./transformation/utils/lualib";
export declare enum SyntaxKind {
Block = 0,
DoStatement = 1,
VariableDeclarationStatement = 2,
AssignmentStatement = 3,
IfStatement = 4,
WhileStatement = 5,
RepeatStatement = 6,
ForStatement = 7,
ForInStatement = 8,
GotoStatement = 9,
LabelStatement = 10,
ReturnStatement = 11,
BreakStatement = 12,
ExpressionStatement = 13,
StringLiteral = 14,
NumericLiteral = 15,
NilKeyword = 16,
DotsKeyword = 17,
TrueKeyword = 18,
FalseKeyword = 19,
FunctionExpression = 20,
TableFieldExpression = 21,
TableExpression = 22,
UnaryExpression = 23,
BinaryExpression = 24,
CallExpression = 25,
MethodCallExpression = 26,
Identifier = 27,
TableIndexExpression = 28,
AdditionOperator = 29,
SubtractionOperator = 30,
MultiplicationOperator = 31,
DivisionOperator = 32,
FloorDivisionOperator = 33,
ModuloOperator = 34,
PowerOperator = 35,
NegationOperator = 36,
ConcatOperator = 37,
LengthOperator = 38,
EqualityOperator = 39,
InequalityOperator = 40,
LessThanOperator = 41,
LessEqualOperator = 42,
GreaterThanOperator = 43,
GreaterEqualOperator = 44,
AndOperator = 45,
OrOperator = 46,
NotOperator = 47,
BitwiseAndOperator = 48,
BitwiseOrOperator = 49,
BitwiseExclusiveOrOperator = 50,
BitwiseRightShiftOperator = 51,
BitwiseLeftShiftOperator = 52,
BitwiseNotOperator = 53
File = 0,
Block = 1,
DoStatement = 2,
VariableDeclarationStatement = 3,
AssignmentStatement = 4,
IfStatement = 5,
WhileStatement = 6,
RepeatStatement = 7,
ForStatement = 8,
ForInStatement = 9,
GotoStatement = 10,
LabelStatement = 11,
ReturnStatement = 12,
BreakStatement = 13,
ExpressionStatement = 14,
StringLiteral = 15,
NumericLiteral = 16,
NilKeyword = 17,
DotsKeyword = 18,
TrueKeyword = 19,
FalseKeyword = 20,
FunctionExpression = 21,
TableFieldExpression = 22,
TableExpression = 23,
UnaryExpression = 24,
BinaryExpression = 25,
CallExpression = 26,
MethodCallExpression = 27,
Identifier = 28,
TableIndexExpression = 29,
AdditionOperator = 30,
SubtractionOperator = 31,
MultiplicationOperator = 32,
DivisionOperator = 33,
FloorDivisionOperator = 34,
ModuloOperator = 35,
PowerOperator = 36,
NegationOperator = 37,
ConcatOperator = 38,
LengthOperator = 39,
EqualityOperator = 40,
InequalityOperator = 41,
LessThanOperator = 42,
LessEqualOperator = 43,
GreaterThanOperator = 44,
GreaterEqualOperator = 45,
AndOperator = 46,
OrOperator = 47,
NotOperator = 48,
BitwiseAndOperator = 49,
BitwiseOrOperator = 50,
BitwiseExclusiveOrOperator = 51,
BitwiseRightShiftOperator = 52,
BitwiseLeftShiftOperator = 53,
BitwiseNotOperator = 54
}

@@ -79,2 +81,10 @@ export declare type UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator;

export declare function getOriginalPos(node: Node): TextRange;
export interface File extends Node {
kind: SyntaxKind.File;
statements: Statement[];
luaLibFeatures: Set<LuaLibFeature>;
trivia: string;
}
export declare function isFile(node: Node): node is File;
export declare function createFile(statements: Statement[], luaLibFeatures: Set<LuaLibFeature>, trivia: string, tsOriginal?: ts.Node): File;
export interface Block extends Node {

@@ -81,0 +91,0 @@ kind: SyntaxKind.Block;

@@ -5,3 +5,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.isInlineFunctionExpression = exports.isFunctionDefinition = exports.isAssignmentLeftHandSideExpression = exports.createTableIndexExpression = exports.isTableIndexExpression = exports.createAnonymousIdentifier = exports.cloneIdentifier = exports.createIdentifier = exports.isIdentifier = exports.createMethodCallExpression = exports.isMethodCallExpression = exports.createCallExpression = exports.isCallExpression = exports.createBinaryExpression = exports.isBinaryExpression = exports.createUnaryExpression = exports.isUnaryExpression = exports.createTableExpression = exports.isTableExpression = exports.createTableFieldExpression = exports.isTableFieldExpression = exports.createFunctionExpression = exports.isFunctionExpression = exports.FunctionExpressionFlags = exports.createStringLiteral = exports.isStringLiteral = exports.createNumericLiteral = exports.isNumericLiteral = exports.createDotsLiteral = exports.isDotsLiteral = exports.createBooleanLiteral = exports.isBooleanLiteral = exports.createNilLiteral = exports.isNilLiteral = exports.createExpressionStatement = exports.isExpressionStatement = exports.createBreakStatement = exports.isBreakStatement = exports.createReturnStatement = exports.isReturnStatement = exports.createLabelStatement = exports.isLabelStatement = exports.createGotoStatement = exports.isGotoStatement = exports.createForInStatement = exports.isForInStatement = exports.createForStatement = exports.isForStatement = exports.createRepeatStatement = exports.isRepeatStatement = exports.createWhileStatement = exports.isWhileStatement = exports.isIterationStatement = exports.createIfStatement = exports.isIfStatement = exports.createAssignmentStatement = exports.isAssignmentStatement = exports.createVariableDeclarationStatement = exports.isVariableDeclarationStatement = exports.createDoStatement = exports.isDoStatement = exports.createBlock = exports.isBlock = exports.getOriginalPos = exports.setNodeOriginal = exports.setNodePosition = exports.cloneNode = exports.createNode = exports.SyntaxKind = void 0;
exports.isInlineFunctionExpression = exports.isFunctionDefinition = exports.isAssignmentLeftHandSideExpression = exports.createTableIndexExpression = exports.isTableIndexExpression = exports.createAnonymousIdentifier = exports.cloneIdentifier = exports.createIdentifier = exports.isIdentifier = exports.createMethodCallExpression = exports.isMethodCallExpression = exports.createCallExpression = exports.isCallExpression = exports.createBinaryExpression = exports.isBinaryExpression = exports.createUnaryExpression = exports.isUnaryExpression = exports.createTableExpression = exports.isTableExpression = exports.createTableFieldExpression = exports.isTableFieldExpression = exports.createFunctionExpression = exports.isFunctionExpression = exports.FunctionExpressionFlags = exports.createStringLiteral = exports.isStringLiteral = exports.createNumericLiteral = exports.isNumericLiteral = exports.createDotsLiteral = exports.isDotsLiteral = exports.createBooleanLiteral = exports.isBooleanLiteral = exports.createNilLiteral = exports.isNilLiteral = exports.createExpressionStatement = exports.isExpressionStatement = exports.createBreakStatement = exports.isBreakStatement = exports.createReturnStatement = exports.isReturnStatement = exports.createLabelStatement = exports.isLabelStatement = exports.createGotoStatement = exports.isGotoStatement = exports.createForInStatement = exports.isForInStatement = exports.createForStatement = exports.isForStatement = exports.createRepeatStatement = exports.isRepeatStatement = exports.createWhileStatement = exports.isWhileStatement = exports.isIterationStatement = exports.createIfStatement = exports.isIfStatement = exports.createAssignmentStatement = exports.isAssignmentStatement = exports.createVariableDeclarationStatement = exports.isVariableDeclarationStatement = exports.createDoStatement = exports.isDoStatement = exports.createBlock = exports.isBlock = exports.createFile = exports.isFile = exports.getOriginalPos = exports.setNodeOriginal = exports.setNodePosition = exports.cloneNode = exports.createNode = exports.SyntaxKind = void 0;
// We can elide a lot of nodes especially tokens and keywords

@@ -13,67 +13,68 @@ // because we don't create the AST from text

(function (SyntaxKind) {
SyntaxKind[SyntaxKind["Block"] = 0] = "Block";
SyntaxKind[SyntaxKind["File"] = 0] = "File";
SyntaxKind[SyntaxKind["Block"] = 1] = "Block";
// Statements
SyntaxKind[SyntaxKind["DoStatement"] = 1] = "DoStatement";
SyntaxKind[SyntaxKind["VariableDeclarationStatement"] = 2] = "VariableDeclarationStatement";
SyntaxKind[SyntaxKind["AssignmentStatement"] = 3] = "AssignmentStatement";
SyntaxKind[SyntaxKind["IfStatement"] = 4] = "IfStatement";
SyntaxKind[SyntaxKind["WhileStatement"] = 5] = "WhileStatement";
SyntaxKind[SyntaxKind["RepeatStatement"] = 6] = "RepeatStatement";
SyntaxKind[SyntaxKind["ForStatement"] = 7] = "ForStatement";
SyntaxKind[SyntaxKind["ForInStatement"] = 8] = "ForInStatement";
SyntaxKind[SyntaxKind["GotoStatement"] = 9] = "GotoStatement";
SyntaxKind[SyntaxKind["LabelStatement"] = 10] = "LabelStatement";
SyntaxKind[SyntaxKind["ReturnStatement"] = 11] = "ReturnStatement";
SyntaxKind[SyntaxKind["BreakStatement"] = 12] = "BreakStatement";
SyntaxKind[SyntaxKind["ExpressionStatement"] = 13] = "ExpressionStatement";
SyntaxKind[SyntaxKind["DoStatement"] = 2] = "DoStatement";
SyntaxKind[SyntaxKind["VariableDeclarationStatement"] = 3] = "VariableDeclarationStatement";
SyntaxKind[SyntaxKind["AssignmentStatement"] = 4] = "AssignmentStatement";
SyntaxKind[SyntaxKind["IfStatement"] = 5] = "IfStatement";
SyntaxKind[SyntaxKind["WhileStatement"] = 6] = "WhileStatement";
SyntaxKind[SyntaxKind["RepeatStatement"] = 7] = "RepeatStatement";
SyntaxKind[SyntaxKind["ForStatement"] = 8] = "ForStatement";
SyntaxKind[SyntaxKind["ForInStatement"] = 9] = "ForInStatement";
SyntaxKind[SyntaxKind["GotoStatement"] = 10] = "GotoStatement";
SyntaxKind[SyntaxKind["LabelStatement"] = 11] = "LabelStatement";
SyntaxKind[SyntaxKind["ReturnStatement"] = 12] = "ReturnStatement";
SyntaxKind[SyntaxKind["BreakStatement"] = 13] = "BreakStatement";
SyntaxKind[SyntaxKind["ExpressionStatement"] = 14] = "ExpressionStatement";
// Expression
SyntaxKind[SyntaxKind["StringLiteral"] = 14] = "StringLiteral";
SyntaxKind[SyntaxKind["NumericLiteral"] = 15] = "NumericLiteral";
SyntaxKind[SyntaxKind["NilKeyword"] = 16] = "NilKeyword";
SyntaxKind[SyntaxKind["DotsKeyword"] = 17] = "DotsKeyword";
SyntaxKind[SyntaxKind["TrueKeyword"] = 18] = "TrueKeyword";
SyntaxKind[SyntaxKind["FalseKeyword"] = 19] = "FalseKeyword";
SyntaxKind[SyntaxKind["FunctionExpression"] = 20] = "FunctionExpression";
SyntaxKind[SyntaxKind["TableFieldExpression"] = 21] = "TableFieldExpression";
SyntaxKind[SyntaxKind["TableExpression"] = 22] = "TableExpression";
SyntaxKind[SyntaxKind["UnaryExpression"] = 23] = "UnaryExpression";
SyntaxKind[SyntaxKind["BinaryExpression"] = 24] = "BinaryExpression";
SyntaxKind[SyntaxKind["CallExpression"] = 25] = "CallExpression";
SyntaxKind[SyntaxKind["MethodCallExpression"] = 26] = "MethodCallExpression";
SyntaxKind[SyntaxKind["Identifier"] = 27] = "Identifier";
SyntaxKind[SyntaxKind["TableIndexExpression"] = 28] = "TableIndexExpression";
SyntaxKind[SyntaxKind["StringLiteral"] = 15] = "StringLiteral";
SyntaxKind[SyntaxKind["NumericLiteral"] = 16] = "NumericLiteral";
SyntaxKind[SyntaxKind["NilKeyword"] = 17] = "NilKeyword";
SyntaxKind[SyntaxKind["DotsKeyword"] = 18] = "DotsKeyword";
SyntaxKind[SyntaxKind["TrueKeyword"] = 19] = "TrueKeyword";
SyntaxKind[SyntaxKind["FalseKeyword"] = 20] = "FalseKeyword";
SyntaxKind[SyntaxKind["FunctionExpression"] = 21] = "FunctionExpression";
SyntaxKind[SyntaxKind["TableFieldExpression"] = 22] = "TableFieldExpression";
SyntaxKind[SyntaxKind["TableExpression"] = 23] = "TableExpression";
SyntaxKind[SyntaxKind["UnaryExpression"] = 24] = "UnaryExpression";
SyntaxKind[SyntaxKind["BinaryExpression"] = 25] = "BinaryExpression";
SyntaxKind[SyntaxKind["CallExpression"] = 26] = "CallExpression";
SyntaxKind[SyntaxKind["MethodCallExpression"] = 27] = "MethodCallExpression";
SyntaxKind[SyntaxKind["Identifier"] = 28] = "Identifier";
SyntaxKind[SyntaxKind["TableIndexExpression"] = 29] = "TableIndexExpression";
// Operators
// Arithmetic
SyntaxKind[SyntaxKind["AdditionOperator"] = 29] = "AdditionOperator";
SyntaxKind[SyntaxKind["SubtractionOperator"] = 30] = "SubtractionOperator";
SyntaxKind[SyntaxKind["MultiplicationOperator"] = 31] = "MultiplicationOperator";
SyntaxKind[SyntaxKind["DivisionOperator"] = 32] = "DivisionOperator";
SyntaxKind[SyntaxKind["FloorDivisionOperator"] = 33] = "FloorDivisionOperator";
SyntaxKind[SyntaxKind["ModuloOperator"] = 34] = "ModuloOperator";
SyntaxKind[SyntaxKind["PowerOperator"] = 35] = "PowerOperator";
SyntaxKind[SyntaxKind["NegationOperator"] = 36] = "NegationOperator";
SyntaxKind[SyntaxKind["AdditionOperator"] = 30] = "AdditionOperator";
SyntaxKind[SyntaxKind["SubtractionOperator"] = 31] = "SubtractionOperator";
SyntaxKind[SyntaxKind["MultiplicationOperator"] = 32] = "MultiplicationOperator";
SyntaxKind[SyntaxKind["DivisionOperator"] = 33] = "DivisionOperator";
SyntaxKind[SyntaxKind["FloorDivisionOperator"] = 34] = "FloorDivisionOperator";
SyntaxKind[SyntaxKind["ModuloOperator"] = 35] = "ModuloOperator";
SyntaxKind[SyntaxKind["PowerOperator"] = 36] = "PowerOperator";
SyntaxKind[SyntaxKind["NegationOperator"] = 37] = "NegationOperator";
// Concat
SyntaxKind[SyntaxKind["ConcatOperator"] = 37] = "ConcatOperator";
SyntaxKind[SyntaxKind["ConcatOperator"] = 38] = "ConcatOperator";
// Length
SyntaxKind[SyntaxKind["LengthOperator"] = 38] = "LengthOperator";
SyntaxKind[SyntaxKind["LengthOperator"] = 39] = "LengthOperator";
// Relational Ops
SyntaxKind[SyntaxKind["EqualityOperator"] = 39] = "EqualityOperator";
SyntaxKind[SyntaxKind["InequalityOperator"] = 40] = "InequalityOperator";
SyntaxKind[SyntaxKind["LessThanOperator"] = 41] = "LessThanOperator";
SyntaxKind[SyntaxKind["LessEqualOperator"] = 42] = "LessEqualOperator";
SyntaxKind[SyntaxKind["EqualityOperator"] = 40] = "EqualityOperator";
SyntaxKind[SyntaxKind["InequalityOperator"] = 41] = "InequalityOperator";
SyntaxKind[SyntaxKind["LessThanOperator"] = 42] = "LessThanOperator";
SyntaxKind[SyntaxKind["LessEqualOperator"] = 43] = "LessEqualOperator";
// Syntax Sugar `x > y` <=> `not (y <= x)`
// but we should probably use them to make the output code more readable
SyntaxKind[SyntaxKind["GreaterThanOperator"] = 43] = "GreaterThanOperator";
SyntaxKind[SyntaxKind["GreaterEqualOperator"] = 44] = "GreaterEqualOperator";
SyntaxKind[SyntaxKind["GreaterThanOperator"] = 44] = "GreaterThanOperator";
SyntaxKind[SyntaxKind["GreaterEqualOperator"] = 45] = "GreaterEqualOperator";
// Logical
SyntaxKind[SyntaxKind["AndOperator"] = 45] = "AndOperator";
SyntaxKind[SyntaxKind["OrOperator"] = 46] = "OrOperator";
SyntaxKind[SyntaxKind["NotOperator"] = 47] = "NotOperator";
SyntaxKind[SyntaxKind["AndOperator"] = 46] = "AndOperator";
SyntaxKind[SyntaxKind["OrOperator"] = 47] = "OrOperator";
SyntaxKind[SyntaxKind["NotOperator"] = 48] = "NotOperator";
// Bitwise
SyntaxKind[SyntaxKind["BitwiseAndOperator"] = 48] = "BitwiseAndOperator";
SyntaxKind[SyntaxKind["BitwiseOrOperator"] = 49] = "BitwiseOrOperator";
SyntaxKind[SyntaxKind["BitwiseExclusiveOrOperator"] = 50] = "BitwiseExclusiveOrOperator";
SyntaxKind[SyntaxKind["BitwiseRightShiftOperator"] = 51] = "BitwiseRightShiftOperator";
SyntaxKind[SyntaxKind["BitwiseLeftShiftOperator"] = 52] = "BitwiseLeftShiftOperator";
SyntaxKind[SyntaxKind["BitwiseNotOperator"] = 53] = "BitwiseNotOperator";
SyntaxKind[SyntaxKind["BitwiseAndOperator"] = 49] = "BitwiseAndOperator";
SyntaxKind[SyntaxKind["BitwiseOrOperator"] = 50] = "BitwiseOrOperator";
SyntaxKind[SyntaxKind["BitwiseExclusiveOrOperator"] = 51] = "BitwiseExclusiveOrOperator";
SyntaxKind[SyntaxKind["BitwiseRightShiftOperator"] = 52] = "BitwiseRightShiftOperator";
SyntaxKind[SyntaxKind["BitwiseLeftShiftOperator"] = 53] = "BitwiseLeftShiftOperator";
SyntaxKind[SyntaxKind["BitwiseNotOperator"] = 54] = "BitwiseNotOperator";
})(SyntaxKind = exports.SyntaxKind || (exports.SyntaxKind = {}));

@@ -124,2 +125,14 @@ function createNode(kind, tsOriginal) {

exports.getOriginalPos = getOriginalPos;
function isFile(node) {
return node.kind === SyntaxKind.File;
}
exports.isFile = isFile;
function createFile(statements, luaLibFeatures, trivia, tsOriginal) {
const file = createNode(SyntaxKind.File, tsOriginal);
file.statements = statements;
file.luaLibFeatures = luaLibFeatures;
file.trivia = trivia;
return file;
}
exports.createFile = createFile;
function isBlock(node) {

@@ -126,0 +139,0 @@ return node.kind === SyntaxKind.Block;

@@ -29,4 +29,7 @@ import { EmitHost } from "./transpilation";

ClassExtends = "ClassExtends",
CloneDescriptor = "CloneDescriptor",
Decorate = "Decorate",
Descriptors = "Descriptors",
DecorateParam = "DecorateParam",
Delete = "Delete",
DelegatedYield = "DelegatedYield",
Error = "Error",

@@ -46,8 +49,14 @@ FunctionBind = "FunctionBind",

ObjectAssign = "ObjectAssign",
ObjectDefineProperty = "ObjectDefineProperty",
ObjectEntries = "ObjectEntries",
ObjectFromEntries = "ObjectFromEntries",
ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor",
ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors",
ObjectKeys = "ObjectKeys",
ObjectRest = "ObjectRest",
ObjectValues = "ObjectValues",
ParseFloat = "ParseFloat",
ParseInt = "ParseInt",
Set = "Set",
SetDescriptor = "SetDescriptor",
WeakMap = "WeakMap",

@@ -54,0 +63,0 @@ WeakSet = "WeakSet",

@@ -33,4 +33,7 @@ "use strict";

LuaLibFeature["ClassExtends"] = "ClassExtends";
LuaLibFeature["CloneDescriptor"] = "CloneDescriptor";
LuaLibFeature["Decorate"] = "Decorate";
LuaLibFeature["Descriptors"] = "Descriptors";
LuaLibFeature["DecorateParam"] = "DecorateParam";
LuaLibFeature["Delete"] = "Delete";
LuaLibFeature["DelegatedYield"] = "DelegatedYield";
LuaLibFeature["Error"] = "Error";

@@ -50,8 +53,14 @@ LuaLibFeature["FunctionBind"] = "FunctionBind";

LuaLibFeature["ObjectAssign"] = "ObjectAssign";
LuaLibFeature["ObjectDefineProperty"] = "ObjectDefineProperty";
LuaLibFeature["ObjectEntries"] = "ObjectEntries";
LuaLibFeature["ObjectFromEntries"] = "ObjectFromEntries";
LuaLibFeature["ObjectGetOwnPropertyDescriptor"] = "ObjectGetOwnPropertyDescriptor";
LuaLibFeature["ObjectGetOwnPropertyDescriptors"] = "ObjectGetOwnPropertyDescriptors";
LuaLibFeature["ObjectKeys"] = "ObjectKeys";
LuaLibFeature["ObjectRest"] = "ObjectRest";
LuaLibFeature["ObjectValues"] = "ObjectValues";
LuaLibFeature["ParseFloat"] = "ParseFloat";
LuaLibFeature["ParseInt"] = "ParseInt";
LuaLibFeature["Set"] = "Set";
LuaLibFeature["SetDescriptor"] = "SetDescriptor";
LuaLibFeature["WeakMap"] = "WeakMap";

@@ -85,2 +94,4 @@ LuaLibFeature["WeakSet"] = "WeakSet";

ArrayFlatMap: [LuaLibFeature.ArrayConcat],
Decorate: [LuaLibFeature.CloneDescriptor],
Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors],
Error: [LuaLibFeature.New, LuaLibFeature.Class],

@@ -91,2 +102,3 @@ FunctionBind: [LuaLibFeature.Unpack],

Iterator: [LuaLibFeature.Symbol],
ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor],
ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol],

@@ -93,0 +105,0 @@ Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class],

import { SourceNode } from "source-map";
import * as ts from "typescript";
import * as lua from "./LuaAST";
import { LuaLibFeature } from "./LuaLib";
import { EmitHost } from "./transpilation";
export declare const escapeString: (value: string) => string;
declare type SourceChunk = string | SourceNode;
export declare type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, block: lua.Block, luaLibFeatures: Set<LuaLibFeature>) => PrintResult;
export declare type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, file: lua.File) => PrintResult;
export interface PrintResult {

@@ -22,6 +21,6 @@ code: string;

constructor(emitHost: EmitHost, program: ts.Program, fileName: string);
print(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>): PrintResult;
print(file: lua.File): PrintResult;
private printInlineSourceMap;
private printStackTraceOverride;
private printImplementation;
private printFile;
protected pushIndent(): void;

@@ -28,0 +27,0 @@ protected popIndent(): void;

@@ -62,3 +62,3 @@ "use strict";

if (printers.length === 0) {
return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args);
return (program, emitHost, fileName, file) => new LuaPrinter(emitHost, program, fileName).print(file);
}

@@ -73,594 +73,590 @@ else if (printers.length === 1) {

exports.createPrinter = createPrinter;
let LuaPrinter = /** @class */ (() => {
class LuaPrinter {
constructor(emitHost, program, fileName) {
this.emitHost = emitHost;
this.currentIndent = "";
this.options = program.getCompilerOptions();
if (this.options.outDir) {
const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName);
if (this.options.sourceRoot) {
// When sourceRoot is specified, just use relative path inside rootDir
this.sourceFile = relativeFileName;
}
else {
// Calculate relative path from rootDir to outDir
const outputPath = path.resolve(this.options.outDir, relativeFileName);
this.sourceFile = path.relative(path.dirname(outputPath), fileName);
}
// We want forward slashes, even in windows
this.sourceFile = utils_1.normalizeSlashes(this.sourceFile);
class LuaPrinter {
constructor(emitHost, program, fileName) {
this.emitHost = emitHost;
this.currentIndent = "";
this.options = program.getCompilerOptions();
if (this.options.outDir) {
const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName);
if (this.options.sourceRoot) {
// When sourceRoot is specified, just use relative path inside rootDir
this.sourceFile = relativeFileName;
}
else {
this.sourceFile = path.basename(fileName); // File will be in same dir as source
// Calculate relative path from rootDir to outDir
const outputPath = path.resolve(this.options.outDir, relativeFileName);
this.sourceFile = path.relative(path.dirname(outputPath), fileName);
}
// We want forward slashes, even in windows
this.sourceFile = utils_1.normalizeSlashes(this.sourceFile);
}
print(block, luaLibFeatures) {
// Add traceback lualib if sourcemap traceback option is enabled
if (this.options.sourceMapTraceback) {
luaLibFeatures.add(LuaLib_1.LuaLibFeature.SourceMapTraceBack);
}
const sourceRoot = this.options.sourceRoot
? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included
this.options.sourceRoot.replace(/[\\/]+$/, "") + "/"
: "";
const rootSourceNode = this.printImplementation(block, luaLibFeatures);
const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode);
let code = rootSourceNode.toString();
if (this.options.inlineSourceMap) {
code += "\n" + this.printInlineSourceMap(sourceMap);
}
if (this.options.sourceMapTraceback) {
const stackTraceOverride = this.printStackTraceOverride(rootSourceNode);
code = code.replace("{#SourceMapTraceback}", stackTraceOverride);
}
return { code, sourceMap: sourceMap.toString(), sourceMapNode: rootSourceNode };
else {
this.sourceFile = path.basename(fileName); // File will be in same dir as source
}
printInlineSourceMap(sourceMap) {
const map = sourceMap.toString();
const base64Map = Buffer.from(map).toString("base64");
return `--# sourceMappingURL=data:application/json;base64,${base64Map}\n`;
}
print(file) {
// Add traceback lualib if sourcemap traceback option is enabled
if (this.options.sourceMapTraceback) {
file.luaLibFeatures.add(LuaLib_1.LuaLibFeature.SourceMapTraceBack);
}
printStackTraceOverride(rootNode) {
let currentLine = 1;
const map = {};
rootNode.walk((chunk, mappedPosition) => {
if (mappedPosition.line !== undefined && mappedPosition.line > 0) {
if (map[currentLine] === undefined) {
map[currentLine] = mappedPosition.line;
}
else {
map[currentLine] = Math.min(map[currentLine], mappedPosition.line);
}
const sourceRoot = this.options.sourceRoot
? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included
this.options.sourceRoot.replace(/[\\/]+$/, "") + "/"
: "";
const rootSourceNode = this.printFile(file);
const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode);
let code = rootSourceNode.toString();
if (this.options.inlineSourceMap) {
code += "\n" + this.printInlineSourceMap(sourceMap);
}
if (this.options.sourceMapTraceback) {
const stackTraceOverride = this.printStackTraceOverride(rootSourceNode);
code = code.replace("{#SourceMapTraceback}", stackTraceOverride);
}
return { code, sourceMap: sourceMap.toString(), sourceMapNode: rootSourceNode };
}
printInlineSourceMap(sourceMap) {
const map = sourceMap.toString();
const base64Map = Buffer.from(map).toString("base64");
return `--# sourceMappingURL=data:application/json;base64,${base64Map}\n`;
}
printStackTraceOverride(rootNode) {
let currentLine = 1;
const map = {};
rootNode.walk((chunk, mappedPosition) => {
if (mappedPosition.line !== undefined && mappedPosition.line > 0) {
if (map[currentLine] === undefined) {
map[currentLine] = mappedPosition.line;
}
currentLine += chunk.split("\n").length - 1;
});
const mapItems = Object.entries(map).map(([line, original]) => `["${line}"] = ${original}`);
const mapString = "{" + mapItems.join(",") + "}";
return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`;
}
printImplementation(block, luaLibFeatures) {
var _a;
let header = "";
if (!this.options.noHeader) {
header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
else {
map[currentLine] = Math.min(map[currentLine], mappedPosition.line);
}
}
const luaLibImport = (_a = this.options.luaLibImport) !== null && _a !== void 0 ? _a : CompilerOptions_1.LuaLibImportKind.Require;
if (luaLibImport === CompilerOptions_1.LuaLibImportKind.Always ||
(luaLibImport === CompilerOptions_1.LuaLibImportKind.Require && luaLibFeatures.size > 0)) {
// Require lualib bundle
header += 'require("lualib_bundle");\n';
}
else if (luaLibImport === CompilerOptions_1.LuaLibImportKind.Inline && luaLibFeatures.size > 0) {
// Inline lualib features
header += "-- Lua Library inline imports\n";
header += LuaLib_1.loadLuaLibFeatures(luaLibFeatures, this.emitHost);
}
if (this.options.sourceMapTraceback) {
header += "{#SourceMapTraceback}\n";
}
const fileBlockNode = this.printBlock(block);
return this.concatNodes(header, fileBlockNode);
currentLine += chunk.split("\n").length - 1;
});
const mapItems = Object.entries(map).map(([line, original]) => `["${line}"] = ${original}`);
const mapString = "{" + mapItems.join(",") + "}";
return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`;
}
printFile(file) {
var _a;
let header = file.trivia;
if (!this.options.noHeader) {
header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
}
pushIndent() {
this.currentIndent += " ";
const luaLibImport = (_a = this.options.luaLibImport) !== null && _a !== void 0 ? _a : CompilerOptions_1.LuaLibImportKind.Require;
if (luaLibImport === CompilerOptions_1.LuaLibImportKind.Always ||
(luaLibImport === CompilerOptions_1.LuaLibImportKind.Require && file.luaLibFeatures.size > 0)) {
// Require lualib bundle
header += 'require("lualib_bundle");\n';
}
popIndent() {
this.currentIndent = this.currentIndent.slice(4);
else if (luaLibImport === CompilerOptions_1.LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) {
// Inline lualib features
header += "-- Lua Library inline imports\n";
header += LuaLib_1.loadLuaLibFeatures(file.luaLibFeatures, this.emitHost);
}
indent(input = "") {
return this.concatNodes(this.currentIndent, input);
if (this.options.sourceMapTraceback) {
header += "{#SourceMapTraceback}\n";
}
createSourceNode(node, chunks, name) {
const { line, column } = lua.getOriginalPos(node);
return line !== undefined && column !== undefined
? new source_map_1.SourceNode(line + 1, column, this.sourceFile, chunks, name)
: new source_map_1.SourceNode(null, null, this.sourceFile, chunks, name);
}
concatNodes(...chunks) {
return new source_map_1.SourceNode(null, null, this.sourceFile, chunks);
}
printBlock(block) {
return this.concatNodes(...this.printStatementArray(block.statements));
}
statementMayRequireSemiColon(statement) {
// Types of statements that could create ambiguous syntax if followed by parenthesis
return (lua.isVariableDeclarationStatement(statement) ||
lua.isAssignmentStatement(statement) ||
lua.isExpressionStatement(statement));
}
nodeStartsWithParenthesis(sourceNode) {
let result;
sourceNode.walk(chunk => {
if (result === undefined) {
chunk = chunk.trimLeft(); // Ignore leading whitespace
if (chunk.length > 0) {
result = chunk.startsWith("(");
}
return this.concatNodes(header, ...this.printStatementArray(file.statements));
}
pushIndent() {
this.currentIndent += " ";
}
popIndent() {
this.currentIndent = this.currentIndent.slice(4);
}
indent(input = "") {
return this.concatNodes(this.currentIndent, input);
}
createSourceNode(node, chunks, name) {
const { line, column } = lua.getOriginalPos(node);
return line !== undefined && column !== undefined
? new source_map_1.SourceNode(line + 1, column, this.sourceFile, chunks, name)
: new source_map_1.SourceNode(null, null, this.sourceFile, chunks, name);
}
concatNodes(...chunks) {
return new source_map_1.SourceNode(null, null, this.sourceFile, chunks);
}
printBlock(block) {
return this.concatNodes(...this.printStatementArray(block.statements));
}
statementMayRequireSemiColon(statement) {
// Types of statements that could create ambiguous syntax if followed by parenthesis
return (lua.isVariableDeclarationStatement(statement) ||
lua.isAssignmentStatement(statement) ||
lua.isExpressionStatement(statement));
}
nodeStartsWithParenthesis(sourceNode) {
let result;
sourceNode.walk(chunk => {
if (result === undefined) {
chunk = chunk.trimLeft(); // Ignore leading whitespace
if (chunk.length > 0) {
result = chunk.startsWith("(");
}
});
return result || false;
}
printStatementArray(statements) {
const statementNodes = [];
for (const [index, statement] of statements.entries()) {
const node = this.printStatement(statement);
if (index > 0 &&
this.statementMayRequireSemiColon(statements[index - 1]) &&
this.nodeStartsWithParenthesis(node)) {
statementNodes[index - 1].add(";");
}
statementNodes.push(node);
if (lua.isReturnStatement(statement))
break;
}
return statementNodes.length > 0 ? [...utils_1.intersperse(statementNodes, "\n"), "\n"] : [];
}
printStatement(statement) {
switch (statement.kind) {
case lua.SyntaxKind.DoStatement:
return this.printDoStatement(statement);
case lua.SyntaxKind.VariableDeclarationStatement:
return this.printVariableDeclarationStatement(statement);
case lua.SyntaxKind.AssignmentStatement:
return this.printVariableAssignmentStatement(statement);
case lua.SyntaxKind.IfStatement:
return this.printIfStatement(statement);
case lua.SyntaxKind.WhileStatement:
return this.printWhileStatement(statement);
case lua.SyntaxKind.RepeatStatement:
return this.printRepeatStatement(statement);
case lua.SyntaxKind.ForStatement:
return this.printForStatement(statement);
case lua.SyntaxKind.ForInStatement:
return this.printForInStatement(statement);
case lua.SyntaxKind.GotoStatement:
return this.printGotoStatement(statement);
case lua.SyntaxKind.LabelStatement:
return this.printLabelStatement(statement);
case lua.SyntaxKind.ReturnStatement:
return this.printReturnStatement(statement);
case lua.SyntaxKind.BreakStatement:
return this.printBreakStatement(statement);
case lua.SyntaxKind.ExpressionStatement:
return this.printExpressionStatement(statement);
default:
throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[statement.kind]}`);
});
return result || false;
}
printStatementArray(statements) {
const statementNodes = [];
for (const [index, statement] of statements.entries()) {
const node = this.printStatement(statement);
if (index > 0 &&
this.statementMayRequireSemiColon(statements[index - 1]) &&
this.nodeStartsWithParenthesis(node)) {
statementNodes[index - 1].add(";");
}
statementNodes.push(node);
if (lua.isReturnStatement(statement))
break;
}
printDoStatement(statement) {
const chunks = [];
chunks.push(this.indent("do\n"));
this.pushIndent();
chunks.push(...this.printStatementArray(statement.statements));
this.popIndent();
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
return statementNodes.length > 0 ? [...utils_1.intersperse(statementNodes, "\n"), "\n"] : [];
}
printStatement(statement) {
switch (statement.kind) {
case lua.SyntaxKind.DoStatement:
return this.printDoStatement(statement);
case lua.SyntaxKind.VariableDeclarationStatement:
return this.printVariableDeclarationStatement(statement);
case lua.SyntaxKind.AssignmentStatement:
return this.printVariableAssignmentStatement(statement);
case lua.SyntaxKind.IfStatement:
return this.printIfStatement(statement);
case lua.SyntaxKind.WhileStatement:
return this.printWhileStatement(statement);
case lua.SyntaxKind.RepeatStatement:
return this.printRepeatStatement(statement);
case lua.SyntaxKind.ForStatement:
return this.printForStatement(statement);
case lua.SyntaxKind.ForInStatement:
return this.printForInStatement(statement);
case lua.SyntaxKind.GotoStatement:
return this.printGotoStatement(statement);
case lua.SyntaxKind.LabelStatement:
return this.printLabelStatement(statement);
case lua.SyntaxKind.ReturnStatement:
return this.printReturnStatement(statement);
case lua.SyntaxKind.BreakStatement:
return this.printBreakStatement(statement);
case lua.SyntaxKind.ExpressionStatement:
return this.printExpressionStatement(statement);
default:
throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[statement.kind]}`);
}
printVariableDeclarationStatement(statement) {
const chunks = [];
chunks.push(this.indent("local "));
if (lua.isFunctionDefinition(statement)) {
// Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion
chunks.push(this.printFunctionDefinition(statement));
}
printDoStatement(statement) {
const chunks = [];
chunks.push(this.indent("do\n"));
this.pushIndent();
chunks.push(...this.printStatementArray(statement.statements));
this.popIndent();
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
}
printVariableDeclarationStatement(statement) {
const chunks = [];
chunks.push(this.indent("local "));
if (lua.isFunctionDefinition(statement)) {
// Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion
chunks.push(this.printFunctionDefinition(statement));
}
else {
chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e))));
if (statement.right) {
chunks.push(" = ");
chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e))));
}
else {
chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e))));
if (statement.right) {
chunks.push(" = ");
chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e))));
}
}
return this.createSourceNode(statement, chunks);
}
printVariableAssignmentStatement(statement) {
const chunks = [];
chunks.push(this.indent());
if (lua.isFunctionDefinition(statement) &&
(statement.right[0].flags & lua.FunctionExpressionFlags.Declaration) !== 0) {
// Use `function foo()` instead of `foo = function()`
const name = this.printExpression(statement.left[0]);
if (isValidLuaFunctionDeclarationName(name.toString())) {
chunks.push(this.printFunctionDefinition(statement));
return this.createSourceNode(statement, chunks);
}
return this.createSourceNode(statement, chunks);
}
printVariableAssignmentStatement(statement) {
const chunks = [];
chunks.push(this.indent());
if (lua.isFunctionDefinition(statement) &&
(statement.right[0].flags & lua.FunctionExpressionFlags.Declaration) !== 0) {
// Use `function foo()` instead of `foo = function()`
const name = this.printExpression(statement.left[0]);
if (isValidLuaFunctionDeclarationName(name.toString())) {
chunks.push(this.printFunctionDefinition(statement));
return this.createSourceNode(statement, chunks);
}
chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e))));
chunks.push(" = ");
chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e))));
return this.createSourceNode(statement, chunks);
}
printIfStatement(statement, isElseIf = false) {
const chunks = [];
const prefix = isElseIf ? "elseif" : "if";
chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n");
this.pushIndent();
chunks.push(this.printBlock(statement.ifBlock));
this.popIndent();
if (statement.elseBlock) {
if (lua.isIfStatement(statement.elseBlock)) {
chunks.push(this.printIfStatement(statement.elseBlock, true));
}
else {
chunks.push(this.indent("else\n"));
this.pushIndent();
chunks.push(this.printBlock(statement.elseBlock));
this.popIndent();
chunks.push(this.indent("end"));
}
chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e))));
chunks.push(" = ");
chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e))));
return this.createSourceNode(statement, chunks);
}
printIfStatement(statement, isElseIf = false) {
const chunks = [];
const prefix = isElseIf ? "elseif" : "if";
chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n");
this.pushIndent();
chunks.push(this.printBlock(statement.ifBlock));
this.popIndent();
if (statement.elseBlock) {
if (lua.isIfStatement(statement.elseBlock)) {
chunks.push(this.printIfStatement(statement.elseBlock, true));
}
else {
chunks.push(this.indent("else\n"));
this.pushIndent();
chunks.push(this.printBlock(statement.elseBlock));
this.popIndent();
chunks.push(this.indent("end"));
}
return this.concatNodes(...chunks);
}
printWhileStatement(statement) {
const chunks = [];
chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
else {
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
}
printRepeatStatement(statement) {
const chunks = [];
chunks.push(this.indent("repeat\n"));
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("until "), this.printExpression(statement.condition));
return this.concatNodes(...chunks);
return this.concatNodes(...chunks);
}
printWhileStatement(statement) {
const chunks = [];
chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
}
printRepeatStatement(statement) {
const chunks = [];
chunks.push(this.indent("repeat\n"));
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("until "), this.printExpression(statement.condition));
return this.concatNodes(...chunks);
}
printForStatement(statement) {
const ctrlVar = this.printExpression(statement.controlVariable);
const ctrlVarInit = this.printExpression(statement.controlVariableInitializer);
const limit = this.printExpression(statement.limitExpression);
const chunks = [];
chunks.push(this.indent("for "), ctrlVar, " = ", ctrlVarInit, ", ", limit);
if (statement.stepExpression) {
chunks.push(", ", this.printExpression(statement.stepExpression));
}
printForStatement(statement) {
const ctrlVar = this.printExpression(statement.controlVariable);
const ctrlVarInit = this.printExpression(statement.controlVariableInitializer);
const limit = this.printExpression(statement.limitExpression);
const chunks = [];
chunks.push(this.indent("for "), ctrlVar, " = ", ctrlVarInit, ", ", limit);
if (statement.stepExpression) {
chunks.push(", ", this.printExpression(statement.stepExpression));
}
chunks.push(" do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
chunks.push(" do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("end"));
return this.concatNodes(...chunks);
}
printForInStatement(statement) {
const names = this.joinChunksWithComma(statement.names.map(i => this.printIdentifier(i)));
const expressions = this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e)));
const chunks = [];
chunks.push(this.indent("for "), ...names, " in ", ...expressions, " do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("end"));
return this.createSourceNode(statement, chunks);
}
printGotoStatement(statement) {
return this.createSourceNode(statement, [this.indent("goto "), statement.label]);
}
printLabelStatement(statement) {
return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]);
}
printReturnStatement(statement) {
if (statement.expressions.length === 0) {
return this.createSourceNode(statement, this.indent("return"));
}
printForInStatement(statement) {
const names = this.joinChunksWithComma(statement.names.map(i => this.printIdentifier(i)));
const expressions = this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e)));
const chunks = [];
chunks.push(this.indent("for "), ...names, " in ", ...expressions, " do\n");
this.pushIndent();
chunks.push(this.printBlock(statement.body));
this.popIndent();
chunks.push(this.indent("end"));
return this.createSourceNode(statement, chunks);
const chunks = [];
chunks.push(...this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e))));
return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]);
}
printBreakStatement(statement) {
return this.createSourceNode(statement, this.indent("break"));
}
printExpressionStatement(statement) {
return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]);
}
// Expressions
printExpression(expression) {
switch (expression.kind) {
case lua.SyntaxKind.StringLiteral:
return this.printStringLiteral(expression);
case lua.SyntaxKind.NumericLiteral:
return this.printNumericLiteral(expression);
case lua.SyntaxKind.NilKeyword:
return this.printNilLiteral(expression);
case lua.SyntaxKind.DotsKeyword:
return this.printDotsLiteral(expression);
case lua.SyntaxKind.TrueKeyword:
case lua.SyntaxKind.FalseKeyword:
return this.printBooleanLiteral(expression);
case lua.SyntaxKind.FunctionExpression:
return this.printFunctionExpression(expression);
case lua.SyntaxKind.TableFieldExpression:
return this.printTableFieldExpression(expression);
case lua.SyntaxKind.TableExpression:
return this.printTableExpression(expression);
case lua.SyntaxKind.UnaryExpression:
return this.printUnaryExpression(expression);
case lua.SyntaxKind.BinaryExpression:
return this.printBinaryExpression(expression);
case lua.SyntaxKind.CallExpression:
return this.printCallExpression(expression);
case lua.SyntaxKind.MethodCallExpression:
return this.printMethodCallExpression(expression);
case lua.SyntaxKind.Identifier:
return this.printIdentifier(expression);
case lua.SyntaxKind.TableIndexExpression:
return this.printTableIndexExpression(expression);
default:
throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`);
}
printGotoStatement(statement) {
return this.createSourceNode(statement, [this.indent("goto "), statement.label]);
}
printStringLiteral(expression) {
return this.createSourceNode(expression, exports.escapeString(expression.value));
}
printNumericLiteral(expression) {
return this.createSourceNode(expression, String(expression.value));
}
printNilLiteral(expression) {
return this.createSourceNode(expression, "nil");
}
printDotsLiteral(expression) {
return this.createSourceNode(expression, "...");
}
printBooleanLiteral(expression) {
return this.createSourceNode(expression, expression.kind === lua.SyntaxKind.TrueKeyword ? "true" : "false");
}
printFunctionParameters(expression) {
var _a;
const parameterChunks = ((_a = expression.params) !== null && _a !== void 0 ? _a : []).map(i => this.printIdentifier(i));
if (expression.dots) {
parameterChunks.push(this.printDotsLiteral(expression.dots));
}
printLabelStatement(statement) {
return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]);
return this.joinChunksWithComma(parameterChunks);
}
printFunctionExpression(expression) {
const chunks = [];
chunks.push("function(");
chunks.push(...this.printFunctionParameters(expression));
chunks.push(")");
if (lua.isInlineFunctionExpression(expression)) {
const returnStatement = expression.body.statements[0];
chunks.push(" ");
const returnNode = [
"return ",
...this.joinChunksWithComma(returnStatement.expressions.map(e => this.printExpression(e))),
];
chunks.push(this.createSourceNode(returnStatement, returnNode));
chunks.push(this.createSourceNode(expression, " end"));
}
printReturnStatement(statement) {
if (statement.expressions.length === 0) {
return this.createSourceNode(statement, this.indent("return"));
}
const chunks = [];
chunks.push(...this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e))));
return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]);
}
printBreakStatement(statement) {
return this.createSourceNode(statement, this.indent("break"));
}
printExpressionStatement(statement) {
return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]);
}
// Expressions
printExpression(expression) {
switch (expression.kind) {
case lua.SyntaxKind.StringLiteral:
return this.printStringLiteral(expression);
case lua.SyntaxKind.NumericLiteral:
return this.printNumericLiteral(expression);
case lua.SyntaxKind.NilKeyword:
return this.printNilLiteral(expression);
case lua.SyntaxKind.DotsKeyword:
return this.printDotsLiteral(expression);
case lua.SyntaxKind.TrueKeyword:
case lua.SyntaxKind.FalseKeyword:
return this.printBooleanLiteral(expression);
case lua.SyntaxKind.FunctionExpression:
return this.printFunctionExpression(expression);
case lua.SyntaxKind.TableFieldExpression:
return this.printTableFieldExpression(expression);
case lua.SyntaxKind.TableExpression:
return this.printTableExpression(expression);
case lua.SyntaxKind.UnaryExpression:
return this.printUnaryExpression(expression);
case lua.SyntaxKind.BinaryExpression:
return this.printBinaryExpression(expression);
case lua.SyntaxKind.CallExpression:
return this.printCallExpression(expression);
case lua.SyntaxKind.MethodCallExpression:
return this.printMethodCallExpression(expression);
case lua.SyntaxKind.Identifier:
return this.printIdentifier(expression);
case lua.SyntaxKind.TableIndexExpression:
return this.printTableIndexExpression(expression);
default:
throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`);
}
}
printStringLiteral(expression) {
return this.createSourceNode(expression, exports.escapeString(expression.value));
}
printNumericLiteral(expression) {
return this.createSourceNode(expression, String(expression.value));
}
printNilLiteral(expression) {
return this.createSourceNode(expression, "nil");
}
printDotsLiteral(expression) {
return this.createSourceNode(expression, "...");
}
printBooleanLiteral(expression) {
return this.createSourceNode(expression, expression.kind === lua.SyntaxKind.TrueKeyword ? "true" : "false");
}
printFunctionParameters(expression) {
var _a;
const parameterChunks = ((_a = expression.params) !== null && _a !== void 0 ? _a : []).map(i => this.printIdentifier(i));
if (expression.dots) {
parameterChunks.push(this.printDotsLiteral(expression.dots));
}
return this.joinChunksWithComma(parameterChunks);
}
printFunctionExpression(expression) {
const chunks = [];
chunks.push("function(");
chunks.push(...this.printFunctionParameters(expression));
chunks.push(")");
if (lua.isInlineFunctionExpression(expression)) {
const returnStatement = expression.body.statements[0];
chunks.push(" ");
const returnNode = [
"return ",
...this.joinChunksWithComma(returnStatement.expressions.map(e => this.printExpression(e))),
];
chunks.push(this.createSourceNode(returnStatement, returnNode));
chunks.push(this.createSourceNode(expression, " end"));
}
else {
chunks.push("\n");
this.pushIndent();
chunks.push(this.printBlock(expression.body));
this.popIndent();
chunks.push(this.indent(this.createSourceNode(expression, "end")));
}
return this.createSourceNode(expression, chunks);
}
printFunctionDefinition(statement) {
const expression = statement.right[0];
const chunks = [];
chunks.push("function ");
chunks.push(this.printExpression(statement.left[0]));
chunks.push("(");
chunks.push(...this.printFunctionParameters(expression));
chunks.push(")\n");
else {
chunks.push("\n");
this.pushIndent();
chunks.push(this.printBlock(expression.body));
this.popIndent();
chunks.push(this.indent(this.createSourceNode(statement, "end")));
return this.createSourceNode(expression, chunks);
chunks.push(this.indent(this.createSourceNode(expression, "end")));
}
printTableFieldExpression(expression) {
const chunks = [];
const value = this.printExpression(expression.value);
if (expression.key) {
if (lua.isStringLiteral(expression.key) && safe_names_1.isValidLuaIdentifier(expression.key.value)) {
chunks.push(expression.key.value, " = ", value);
}
else {
chunks.push("[", this.printExpression(expression.key), "] = ", value);
}
return this.createSourceNode(expression, chunks);
}
printFunctionDefinition(statement) {
const expression = statement.right[0];
const chunks = [];
chunks.push("function ");
chunks.push(this.printExpression(statement.left[0]));
chunks.push("(");
chunks.push(...this.printFunctionParameters(expression));
chunks.push(")\n");
this.pushIndent();
chunks.push(this.printBlock(expression.body));
this.popIndent();
chunks.push(this.indent(this.createSourceNode(statement, "end")));
return this.createSourceNode(expression, chunks);
}
printTableFieldExpression(expression) {
const chunks = [];
const value = this.printExpression(expression.value);
if (expression.key) {
if (lua.isStringLiteral(expression.key) && safe_names_1.isValidLuaIdentifier(expression.key.value)) {
chunks.push(expression.key.value, " = ", value);
}
else {
chunks.push(value);
chunks.push("[", this.printExpression(expression.key), "] = ", value);
}
return this.createSourceNode(expression, chunks);
}
printTableExpression(expression) {
return this.createSourceNode(expression, ["{", ...this.printExpressionList(expression.fields), "}"]);
else {
chunks.push(value);
}
printUnaryExpression(expression) {
const chunks = [];
chunks.push(this.printOperator(expression.operator));
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.operand));
return this.createSourceNode(expression, chunks);
return this.createSourceNode(expression, chunks);
}
printTableExpression(expression) {
return this.createSourceNode(expression, ["{", ...this.printExpressionList(expression.fields), "}"]);
}
printUnaryExpression(expression) {
const chunks = [];
chunks.push(this.printOperator(expression.operator));
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.operand));
return this.createSourceNode(expression, chunks);
}
printBinaryExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.left));
chunks.push(" ", this.printOperator(expression.operator), " ");
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.right));
return this.createSourceNode(expression, chunks);
}
printExpressionInParenthesesIfNeeded(expression) {
return this.needsParenthesis(expression)
? this.createSourceNode(expression, ["(", this.printExpression(expression), ")"])
: this.printExpression(expression);
}
needsParenthesis(expression) {
return (lua.isBinaryExpression(expression) ||
lua.isFunctionExpression(expression) ||
lua.isTableExpression(expression) ||
(lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator));
}
printCallExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.expression), "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
}
printBinaryExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.left));
chunks.push(" ", this.printOperator(expression.operator), " ");
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.right));
return this.createSourceNode(expression, chunks);
chunks.push(")");
return this.createSourceNode(expression, chunks);
}
printMethodCallExpression(expression) {
const chunks = [];
const prefix = this.needsParenthesis(expression.prefixExpression) || lua.isStringLiteral(expression.prefixExpression)
? ["(", this.printExpression(expression.prefixExpression), ")"]
: [this.printExpression(expression.prefixExpression)];
const name = this.printIdentifier(expression.name);
chunks.push(...prefix, ":", name, "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
}
printExpressionInParenthesesIfNeeded(expression) {
return this.needsParenthesis(expression)
? this.createSourceNode(expression, ["(", this.printExpression(expression), ")"])
: this.printExpression(expression);
chunks.push(")");
return this.createSourceNode(expression, chunks);
}
printIdentifier(expression) {
return this.createSourceNode(expression, expression.text, expression.originalName !== expression.text ? expression.originalName : undefined);
}
printTableIndexExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.table));
if (lua.isStringLiteral(expression.index) && safe_names_1.isValidLuaIdentifier(expression.index.value)) {
chunks.push(".", this.createSourceNode(expression.index, expression.index.value));
}
needsParenthesis(expression) {
return (lua.isBinaryExpression(expression) ||
lua.isFunctionExpression(expression) ||
lua.isTableExpression(expression) ||
(lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator));
else {
chunks.push("[", this.printExpression(expression.index), "]");
}
printCallExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.expression), "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
}
chunks.push(")");
return this.createSourceNode(expression, chunks);
return this.createSourceNode(expression, chunks);
}
printOperator(kind) {
return new source_map_1.SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]);
}
joinChunksWithComma(chunks) {
return utils_1.intersperse(chunks, ", ");
}
printExpressionList(expressions) {
const chunks = [];
if (expressions.every(isSimpleExpression)) {
chunks.push(...this.joinChunksWithComma(expressions.map(e => this.printExpression(e))));
}
printMethodCallExpression(expression) {
const chunks = [];
const prefix = this.needsParenthesis(expression.prefixExpression) || lua.isStringLiteral(expression.prefixExpression)
? ["(", this.printExpression(expression.prefixExpression), ")"]
: [this.printExpression(expression.prefixExpression)];
const name = this.printIdentifier(expression.name);
chunks.push(...prefix, ":", name, "(");
if (expression.params) {
chunks.push(...this.printExpressionList(expression.params));
else {
chunks.push("\n");
this.pushIndent();
for (const [index, expression] of expressions.entries()) {
const tail = index < expressions.length - 1 ? ",\n" : "\n";
chunks.push(this.indent(), this.printExpression(expression), tail);
}
chunks.push(")");
return this.createSourceNode(expression, chunks);
this.popIndent();
chunks.push(this.indent());
}
printIdentifier(expression) {
return this.createSourceNode(expression, expression.text, expression.originalName !== expression.text ? expression.originalName : undefined);
}
printTableIndexExpression(expression) {
const chunks = [];
chunks.push(this.printExpressionInParenthesesIfNeeded(expression.table));
if (lua.isStringLiteral(expression.index) && safe_names_1.isValidLuaIdentifier(expression.index.value)) {
chunks.push(".", this.createSourceNode(expression.index, expression.index.value));
return chunks;
}
// The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column
// will not generate 'empty' mappings in the source map that point to nothing in the original TS.
buildSourceMap(sourceRoot, rootSourceNode) {
const map = new source_map_1.SourceMapGenerator({
file: utils_1.trimExtension(this.sourceFile) + ".lua",
sourceRoot,
});
let generatedLine = 1;
let generatedColumn = 0;
let currentMapping;
const isNewMapping = (sourceNode) => {
if (sourceNode.line === null) {
return false;
}
else {
chunks.push("[", this.printExpression(expression.index), "]");
if (currentMapping === undefined) {
return true;
}
return this.createSourceNode(expression, chunks);
}
printOperator(kind) {
return new source_map_1.SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]);
}
joinChunksWithComma(chunks) {
return utils_1.intersperse(chunks, ", ");
}
printExpressionList(expressions) {
const chunks = [];
if (expressions.every(isSimpleExpression)) {
chunks.push(...this.joinChunksWithComma(expressions.map(e => this.printExpression(e))));
if (currentMapping.generated.line === generatedLine &&
currentMapping.generated.column === generatedColumn &&
currentMapping.name === sourceNode.name) {
return false;
}
else {
chunks.push("\n");
this.pushIndent();
for (const [index, expression] of expressions.entries()) {
const tail = index < expressions.length - 1 ? ",\n" : "\n";
chunks.push(this.indent(), this.printExpression(expression), tail);
}
this.popIndent();
chunks.push(this.indent());
return (currentMapping.original.line !== sourceNode.line ||
currentMapping.original.column !== sourceNode.column ||
currentMapping.name !== sourceNode.name);
};
const build = (sourceNode) => {
if (isNewMapping(sourceNode)) {
currentMapping = {
source: sourceNode.source,
original: { line: sourceNode.line, column: sourceNode.column },
generated: { line: generatedLine, column: generatedColumn },
name: sourceNode.name,
};
map.addMapping(currentMapping);
}
return chunks;
}
// The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column
// will not generate 'empty' mappings in the source map that point to nothing in the original TS.
buildSourceMap(sourceRoot, rootSourceNode) {
const map = new source_map_1.SourceMapGenerator({
file: utils_1.trimExtension(this.sourceFile) + ".lua",
sourceRoot,
});
let generatedLine = 1;
let generatedColumn = 0;
let currentMapping;
const isNewMapping = (sourceNode) => {
if (sourceNode.line === null) {
return false;
for (const chunk of sourceNode.children) {
if (typeof chunk === "string") {
const lines = chunk.split("\n");
if (lines.length > 1) {
generatedLine += lines.length - 1;
generatedColumn = 0;
currentMapping = undefined; // Mappings end at newlines
}
generatedColumn += lines[lines.length - 1].length;
}
if (currentMapping === undefined) {
return true;
else {
build(chunk);
}
if (currentMapping.generated.line === generatedLine &&
currentMapping.generated.column === generatedColumn &&
currentMapping.name === sourceNode.name) {
return false;
}
return (currentMapping.original.line !== sourceNode.line ||
currentMapping.original.column !== sourceNode.column ||
currentMapping.name !== sourceNode.name);
};
const build = (sourceNode) => {
if (isNewMapping(sourceNode)) {
currentMapping = {
source: sourceNode.source,
original: { line: sourceNode.line, column: sourceNode.column },
generated: { line: generatedLine, column: generatedColumn },
name: sourceNode.name,
};
map.addMapping(currentMapping);
}
for (const chunk of sourceNode.children) {
if (typeof chunk === "string") {
const lines = chunk.split("\n");
if (lines.length > 1) {
generatedLine += lines.length - 1;
generatedColumn = 0;
currentMapping = undefined; // Mappings end at newlines
}
generatedColumn += lines[lines.length - 1].length;
}
else {
build(chunk);
}
}
};
build(rootSourceNode);
return map;
}
}
};
build(rootSourceNode);
return map;
}
LuaPrinter.operatorMap = {
[lua.SyntaxKind.AdditionOperator]: "+",
[lua.SyntaxKind.SubtractionOperator]: "-",
[lua.SyntaxKind.MultiplicationOperator]: "*",
[lua.SyntaxKind.DivisionOperator]: "/",
[lua.SyntaxKind.FloorDivisionOperator]: "//",
[lua.SyntaxKind.ModuloOperator]: "%",
[lua.SyntaxKind.PowerOperator]: "^",
[lua.SyntaxKind.NegationOperator]: "-",
[lua.SyntaxKind.ConcatOperator]: "..",
[lua.SyntaxKind.LengthOperator]: "#",
[lua.SyntaxKind.EqualityOperator]: "==",
[lua.SyntaxKind.InequalityOperator]: "~=",
[lua.SyntaxKind.LessThanOperator]: "<",
[lua.SyntaxKind.LessEqualOperator]: "<=",
[lua.SyntaxKind.GreaterThanOperator]: ">",
[lua.SyntaxKind.GreaterEqualOperator]: ">=",
[lua.SyntaxKind.AndOperator]: "and",
[lua.SyntaxKind.OrOperator]: "or",
[lua.SyntaxKind.NotOperator]: "not ",
[lua.SyntaxKind.BitwiseAndOperator]: "&",
[lua.SyntaxKind.BitwiseOrOperator]: "|",
[lua.SyntaxKind.BitwiseExclusiveOrOperator]: "~",
[lua.SyntaxKind.BitwiseRightShiftOperator]: ">>",
[lua.SyntaxKind.BitwiseLeftShiftOperator]: "<<",
[lua.SyntaxKind.BitwiseNotOperator]: "~",
};
return LuaPrinter;
})();
}
exports.LuaPrinter = LuaPrinter;
LuaPrinter.operatorMap = {
[lua.SyntaxKind.AdditionOperator]: "+",
[lua.SyntaxKind.SubtractionOperator]: "-",
[lua.SyntaxKind.MultiplicationOperator]: "*",
[lua.SyntaxKind.DivisionOperator]: "/",
[lua.SyntaxKind.FloorDivisionOperator]: "//",
[lua.SyntaxKind.ModuloOperator]: "%",
[lua.SyntaxKind.PowerOperator]: "^",
[lua.SyntaxKind.NegationOperator]: "-",
[lua.SyntaxKind.ConcatOperator]: "..",
[lua.SyntaxKind.LengthOperator]: "#",
[lua.SyntaxKind.EqualityOperator]: "==",
[lua.SyntaxKind.InequalityOperator]: "~=",
[lua.SyntaxKind.LessThanOperator]: "<",
[lua.SyntaxKind.LessEqualOperator]: "<=",
[lua.SyntaxKind.GreaterThanOperator]: ">",
[lua.SyntaxKind.GreaterEqualOperator]: ">=",
[lua.SyntaxKind.AndOperator]: "and",
[lua.SyntaxKind.OrOperator]: "or",
[lua.SyntaxKind.NotOperator]: "not ",
[lua.SyntaxKind.BitwiseAndOperator]: "&",
[lua.SyntaxKind.BitwiseOrOperator]: "|",
[lua.SyntaxKind.BitwiseExclusiveOrOperator]: "~",
[lua.SyntaxKind.BitwiseRightShiftOperator]: ">>",
[lua.SyntaxKind.BitwiseLeftShiftOperator]: "<<",
[lua.SyntaxKind.BitwiseNotOperator]: "~",
};
//# sourceMappingURL=LuaPrinter.js.map

@@ -23,2 +23,6 @@ "use strict";

return lualib_1.transformLuaLibFunction(context, name === "isNaN" ? lualib_1.LuaLibFeature.NumberIsNaN : lualib_1.LuaLibFeature.NumberIsFinite, node, ...numberParameters);
case "parseFloat":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ParseFloat, node, ...parameters);
case "parseInt":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ParseInt, node, ...parameters);
}

@@ -25,0 +29,0 @@ }

@@ -10,15 +10,21 @@ "use strict";

const method = expression.expression;
const parameters = call_1.transformArguments(context, expression.arguments);
const args = call_1.transformArguments(context, expression.arguments);
const methodName = method.name.text;
switch (methodName) {
case "assign":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectAssign, expression, ...parameters);
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectAssign, expression, ...args);
case "defineProperty":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectDefineProperty, expression, ...args);
case "entries":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectEntries, expression, ...parameters);
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectEntries, expression, ...args);
case "fromEntries":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectFromEntries, expression, ...parameters);
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectFromEntries, expression, ...args);
case "getOwnPropertyDescriptor":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectGetOwnPropertyDescriptor, expression, ...args);
case "getOwnPropertyDescriptors":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectGetOwnPropertyDescriptors, expression, ...args);
case "keys":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectKeys, expression, ...parameters);
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectKeys, expression, ...args);
case "values":
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectValues, expression, ...parameters);
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectValues, expression, ...args);
default:

@@ -25,0 +31,0 @@ context.diagnostics.push(diagnostics_1.unsupportedProperty(method.name, "Object", methodName));

@@ -10,4 +10,4 @@ "use strict";

var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
}
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -14,0 +14,0 @@ __exportStar(require("./context"), exports);

@@ -135,3 +135,3 @@ import * as ts from "typescript";

export declare type StatementLikeNode = ts.Statement;
export declare type VisitorResult<T extends ts.Node> = T extends ExpressionLikeNode ? lua.Expression : T extends StatementLikeNode ? OneToManyVisitorResult<lua.Statement> : T extends ts.SourceFile ? lua.Block : OneToManyVisitorResult<lua.Node>;
export declare type VisitorResult<T extends ts.Node> = T extends ExpressionLikeNode ? lua.Expression : T extends StatementLikeNode ? OneToManyVisitorResult<lua.Statement> : T extends ts.SourceFile ? lua.File : OneToManyVisitorResult<lua.Node>;
export declare type Visitor<T extends ts.Node> = FunctionVisitor<T> | ObjectVisitor<T>;

@@ -138,0 +138,0 @@ export declare type FunctionVisitor<T extends ts.Node> = (node: T, context: TransformationContext) => VisitorResult<T>;

import * as ts from "typescript";
import * as lua from "../LuaAST";
import { LuaLibFeature } from "../LuaLib";
import { VisitorMap, Visitors } from "./context";
export declare function createVisitorMap(customVisitors: Visitors[]): VisitorMap;
export interface TransformSourceFileResult {
luaAst: lua.Block;
luaLibFeatures: Set<LuaLibFeature>;
export declare function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap): {
file: lua.File;
diagnostics: ts.Diagnostic[];
}
export declare function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap): TransformSourceFileResult;
};

@@ -6,3 +6,2 @@ "use strict";

const context_1 = require("./context");
const lualib_1 = require("./utils/lualib");
const visitors_1 = require("./visitors");

@@ -30,10 +29,6 @@ function createVisitorMap(customVisitors) {

const context = new context_1.TransformationContext(program, sourceFile, visitorMap);
const [luaAst] = context.transformNode(sourceFile);
return {
luaAst,
luaLibFeatures: lualib_1.getUsedLuaLibFeatures(context),
diagnostics: context.diagnostics,
};
const [file] = context.transformNode(sourceFile);
return { file, diagnostics: context.diagnostics };
}
exports.transformSourceFile = transformSourceFile;
//# sourceMappingURL=index.js.map

@@ -24,4 +24,4 @@ "use strict";

validateFunctionAssignment(context, node, fromType, toType, toName);
const fromTypeNode = context.checker.typeToTypeNode(fromType);
const toTypeNode = context.checker.typeToTypeNode(toType);
const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined);
const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined);
if (!fromTypeNode || !toTypeNode) {

@@ -28,0 +28,0 @@ return;

@@ -10,3 +10,2 @@ "use strict";

const scope_1 = require("./scope");
const typescript_1 = require("./typescript");
const lualib_1 = require("./lualib");

@@ -104,2 +103,10 @@ const LuaLib_1 = require("../../LuaLib");

exports.createHoistableVariableDeclarationStatement = createHoistableVariableDeclarationStatement;
function hasMultipleReferences(scope, identifiers) {
const scopeSymbols = scope.referencedSymbols;
if (!scopeSymbols) {
return false;
}
const referenceLists = utils_1.castArray(identifiers).map(i => i.symbolId && scopeSymbols.get(i.symbolId));
return referenceLists.some(symbolRefs => symbolRefs && symbolRefs.length > 1);
}
function createLocalOrExportedOrGlobalDeclaration(context, lhs, rhs, tsOriginal, overrideExportScope) {

@@ -127,9 +134,4 @@ let declaration;

if (context.isModule || !isTopLevelVariable) {
const isPossibleWrappedFunction = !isFunctionDeclaration &&
tsOriginal &&
ts.isVariableDeclaration(tsOriginal) &&
tsOriginal.initializer &&
typescript_1.isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer));
if (isPossibleWrappedFunction || scope.type === scope_1.ScopeType.Switch) {
// Split declaration and assignment for wrapped function types to allow recursion
if (scope.type === scope_1.ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) {
// Split declaration and assignment of identifiers that reference themselves in their declaration
declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal);

@@ -136,0 +138,0 @@ assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal);

@@ -10,4 +10,4 @@ "use strict";

var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
}
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -14,0 +14,0 @@ exports.isExpressionWithEvaluationEffect = exports.getAllCallSignatures = exports.inferAssignedType = exports.hasStandardLibrarySignature = exports.isStandardLibraryType = exports.getFirstDeclarationInFile = exports.findFirstNodeAbove = exports.hasExportEquals = void 0;

@@ -5,3 +5,3 @@ import * as ts from "typescript";

export declare function parseAccessExpressionWithEvaluationEffects(context: TransformationContext, node: ts.Expression): [ts.Expression, ts.Expression] | [];
declare type CompoundAssignmentToken = ts.SyntaxKind.BarToken | ts.SyntaxKind.PlusToken | ts.SyntaxKind.CaretToken | ts.SyntaxKind.MinusToken | ts.SyntaxKind.SlashToken | ts.SyntaxKind.PercentToken | ts.SyntaxKind.AsteriskToken | ts.SyntaxKind.AmpersandToken | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken;
declare type CompoundAssignmentToken = ts.SyntaxKind.BarToken | ts.SyntaxKind.PlusToken | ts.SyntaxKind.CaretToken | ts.SyntaxKind.MinusToken | ts.SyntaxKind.SlashToken | ts.SyntaxKind.PercentToken | ts.SyntaxKind.AsteriskToken | ts.SyntaxKind.AmpersandToken | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.QuestionQuestionToken;
export declare const isCompoundAssignmentToken: (token: ts.BinaryOperator) => token is ts.CompoundAssignmentOperator;

@@ -8,0 +8,0 @@ export declare const unwrapCompoundAssignmentToken: (token: ts.CompoundAssignmentOperator) => CompoundAssignmentToken;

@@ -46,2 +46,5 @@ "use strict";

[ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken,
[ts.SyntaxKind.BarBarEqualsToken]: ts.SyntaxKind.BarBarToken,
[ts.SyntaxKind.AmpersandAmpersandEqualsToken]: ts.SyntaxKind.AmpersandAmpersandToken,
[ts.SyntaxKind.QuestionQuestionEqualsToken]: ts.SyntaxKind.QuestionQuestionToken,
};

@@ -103,2 +106,5 @@ exports.isCompoundAssignmentToken = (token) => token in compoundToAssignmentTokens;

const assignStatements = assignments_1.transformAssignment(context, lhs, tmpIdentifier);
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
return lua_ast_1.createImmediatelyInvokedFunctionExpression([tmpDeclaration, ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs)], tmpIdentifier, expression);
}
return lua_ast_1.createImmediatelyInvokedFunctionExpression([tmpDeclaration, ...assignStatements], tmpIdentifier, expression);

@@ -127,2 +133,8 @@ }

const accessExpression = lua.createTableIndexExpression(obj, index);
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
return [
objAndIndexDeclaration,
...transformSetterSkippingCompoundAssignment(context, accessExpression, operator, rhs, node),
];
}
const operatorExpression = binary_expression_1.transformBinaryOperation(context, accessExpression, right, operator, node);

@@ -133,2 +145,6 @@ const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);

else {
if (isSetterSkippingCompoundAssignmentOperator(operator)) {
const luaLhs = context.transformExpression(lhs);
return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node);
}
// Simple statements

@@ -141,2 +157,27 @@ // ${left} = ${left} ${replacementOperator} ${right}

exports.transformCompoundAssignmentStatement = transformCompoundAssignmentStatement;
function isSetterSkippingCompoundAssignmentOperator(operator) {
return (operator === ts.SyntaxKind.AmpersandAmpersandToken ||
operator === ts.SyntaxKind.BarBarToken ||
operator === ts.SyntaxKind.QuestionQuestionToken);
}
function transformSetterSkippingCompoundAssignment(context, lhs, operator, rhs, node) {
// These assignments have the form 'if x then y = z', figure out what condition x is first.
let condition;
if (operator === ts.SyntaxKind.AmpersandAmpersandToken) {
condition = lhs;
}
else if (operator === ts.SyntaxKind.BarBarToken) {
condition = lua.createUnaryExpression(lhs, lua.SyntaxKind.NotOperator);
}
else if (operator === ts.SyntaxKind.QuestionQuestionToken) {
condition = lua.createBinaryExpression(lhs, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
}
else {
utils_1.assertNever(operator);
}
// if condition then lhs = rhs end
return [
lua.createIfStatement(condition, lua.createBlock([lua.createAssignmentStatement(lhs, context.transformExpression(rhs))]), undefined, node),
];
}
//# sourceMappingURL=compound.js.map

@@ -6,5 +6,5 @@ import * as ts from "typescript";

declare type SimpleOperator = ts.AdditiveOperatorOrHigher | Exclude<ts.RelationalOperator, ts.SyntaxKind.InstanceOfKeyword | ts.SyntaxKind.InKeyword> | ts.EqualityOperator | ts.LogicalOperator;
export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, operator: BitOperator | SimpleOperator, node: ts.Node): lua.Expression;
export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node): lua.Expression;
export declare const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression>;
export declare function transformBinaryExpressionStatement(context: TransformationContext, node: ts.ExpressionStatement): lua.Statement[] | lua.Statement | undefined;
export {};

@@ -15,2 +15,3 @@ "use strict";

const compound_1 = require("./compound");
const utils_1 = require("../../../utils");
const simpleOperatorsToLua = {

@@ -38,2 +39,6 @@ [ts.SyntaxKind.AmpersandAmpersandToken]: lua.SyntaxKind.AndOperator,

}
if (operator === ts.SyntaxKind.QuestionQuestionToken) {
utils_1.assert(ts.isBinaryExpression(node));
return transformNullishCoalescingExpression(context, node);
}
let luaOperator = simpleOperatorsToLua[operator];

@@ -60,3 +65,4 @@ // Check if we need to use string concat operator

if (compound_1.isCompoundAssignmentToken(operator)) {
return compound_1.transformCompoundAssignmentExpression(context, node, node.left, node.right, compound_1.unwrapCompoundAssignmentToken(operator), false);
const token = compound_1.unwrapCompoundAssignmentToken(operator);
return compound_1.transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false);
}

@@ -91,5 +97,2 @@ switch (operator) {

}
case ts.SyntaxKind.QuestionQuestionToken: {
return transformNullishCoalescingExpression(context, node);
}
default:

@@ -106,3 +109,4 @@ return transformBinaryOperation(context, context.transformExpression(node.left), context.transformExpression(node.right), operator, node);

// +=, -=, etc...
return compound_1.transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, compound_1.unwrapCompoundAssignmentToken(operator));
const token = compound_1.unwrapCompoundAssignmentToken(operator);
return compound_1.transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token);
}

@@ -109,0 +113,0 @@ else if (operator === ts.SyntaxKind.EqualsToken) {

import * as ts from "typescript";
import * as lua from "../../../LuaAST";
import { TransformationContext } from "../../context";
export declare function createConstructorDecorationStatement(context: TransformationContext, declaration: ts.ClassLikeDeclaration): lua.AssignmentStatement | undefined;
export declare function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression;
export declare function createDecoratingExpression(context: TransformationContext, kind: ts.SyntaxKind, decorators: lua.Expression[], targetTableName: lua.Expression, targetFieldExpression?: lua.Expression): lua.Expression;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createConstructorDecorationStatement = void 0;
exports.createDecoratingExpression = exports.transformDecoratorExpression = void 0;
const ts = require("typescript");
const lua = require("../../../LuaAST");
const diagnostics_1 = require("../../utils/diagnostics");
const export_1 = require("../../utils/export");
const function_context_1 = require("../../utils/function-context");
const lualib_1 = require("../../utils/lualib");
const identifier_1 = require("../identifier");
function createConstructorDecorationStatement(context, declaration) {
const className = declaration.name !== undefined
? export_1.addExportToIdentifier(context, identifier_1.transformIdentifier(context, declaration.name))
: lua.createAnonymousIdentifier();
const decorators = declaration.decorators;
if (!decorators) {
return undefined;
function transformDecoratorExpression(context, decorator) {
const expression = decorator.expression;
const type = context.checker.getTypeAtLocation(expression);
const callContext = function_context_1.getFunctionContextType(context, type);
if (callContext === function_context_1.ContextType.Void) {
context.diagnostics.push(diagnostics_1.decoratorInvalidContext(decorator));
}
const decoratorExpressions = decorators.map(decorator => {
const expression = decorator.expression;
const type = context.checker.getTypeAtLocation(expression);
const callContext = function_context_1.getFunctionContextType(context, type);
if (callContext === function_context_1.ContextType.Void) {
context.diagnostics.push(diagnostics_1.decoratorInvalidContext(decorator));
}
return context.transformExpression(expression);
});
const decoratorTable = lua.createTableExpression(decoratorExpressions.map(expression => lua.createTableFieldExpression(expression)));
return lua.createAssignmentStatement(className, lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Decorate, undefined, decoratorTable, className));
return context.transformExpression(expression);
}
exports.createConstructorDecorationStatement = createConstructorDecorationStatement;
exports.transformDecoratorExpression = transformDecoratorExpression;
function createDecoratingExpression(context, kind, decorators, targetTableName, targetFieldExpression) {
const decoratorTable = lua.createTableExpression(decorators.map(e => lua.createTableFieldExpression(e)));
const trailingExpressions = [decoratorTable, targetTableName];
if (targetFieldExpression) {
trailingExpressions.push(targetFieldExpression);
const isMethodOrAccessor = kind === ts.SyntaxKind.MethodDeclaration ||
kind === ts.SyntaxKind.GetAccessor ||
kind === ts.SyntaxKind.SetAccessor;
trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral());
}
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Decorate, undefined, ...trailingExpressions);
}
exports.createDecoratingExpression = createDecoratingExpression;
//# sourceMappingURL=decorators.js.map

@@ -95,3 +95,2 @@ "use strict";

// Divide properties into static and non-static
const staticFields = properties.filter(utils_2.isStaticNode);
const instanceFields = properties.filter(prop => !utils_2.isStaticNode(prop));

@@ -183,18 +182,37 @@ const result = [];

}
// Transform methods
result.push(...classDeclaration.members
.filter(ts.isMethodDeclaration)
.map(m => method_1.transformMethodDeclaration(context, m, localClassName, isExtension || isMetaExtension))
.filter(utils_1.isNonNull));
// Add static declarations
for (const field of staticFields) {
const fieldName = literal_1.transformPropertyName(context, field.name);
const value = field.initializer ? context.transformExpression(field.initializer) : undefined;
const classField = lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), fieldName);
const fieldAssign = lua.createAssignmentStatement(classField, value);
result.push(fieldAssign);
const noPrototype = isExtension || isMetaExtension;
const decorationStatements = [];
for (const member of classDeclaration.members) {
if (ts.isAccessor(member)) {
const expression = fields_1.createPropertyDecoratingExpression(context, member, localClassName, noPrototype);
if (expression)
decorationStatements.push(lua.createExpressionStatement(expression));
}
else if (ts.isMethodDeclaration(member)) {
const statement = method_1.transformMethodDeclaration(context, member, localClassName, noPrototype);
if (statement)
result.push(statement);
if (member.body) {
const statement = method_1.createMethodDecoratingExpression(context, member, localClassName, noPrototype);
if (statement)
decorationStatements.push(statement);
}
}
else if (ts.isPropertyDeclaration(member)) {
if (utils_2.isStaticNode(member)) {
const statement = fields_1.transformStaticPropertyDeclaration(context, member, localClassName);
if (statement)
decorationStatements.push(statement);
}
const expression = fields_1.createPropertyDecoratingExpression(context, member, localClassName, noPrototype);
if (expression)
decorationStatements.push(lua.createExpressionStatement(expression));
}
}
const decorationStatement = decorators_1.createConstructorDecorationStatement(context, classDeclaration);
if (decorationStatement) {
result.push(decorationStatement);
result.push(...decorationStatements);
// Decorate the class
if (classDeclaration.decorators) {
const decoratingExpression = decorators_1.createDecoratingExpression(context, classDeclaration.kind, classDeclaration.decorators.map(d => decorators_1.transformDecoratorExpression(context, d)), localClassName);
const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression);
result.push(decoratingStatement);
}

@@ -201,0 +219,0 @@ superInfo.pop();

@@ -11,2 +11,3 @@ "use strict";

const utils_1 = require("../utils");
const constructor_1 = require("./constructor");
function transformAccessor(context, node) {

@@ -28,14 +29,9 @@ const [params, dot, restParam] = function_1.transformParameters(context, node.parameters, lua_ast_1.createSelfIdentifier());

}
lualib_1.importLuaLibFeature(context, lualib_1.LuaLibFeature.Descriptors);
const call = utils_1.isStaticNode(firstAccessor)
? lua.createCallExpression(lua.createIdentifier("__TS__ObjectDefineProperty"), [
lua.cloneIdentifier(className),
propertyName,
descriptor,
])
: lua.createCallExpression(lua.createIdentifier("__TS__SetDescriptor"), [
lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")),
propertyName,
descriptor,
]);
const isStatic = utils_1.isStaticNode(firstAccessor);
const target = isStatic ? lua.cloneIdentifier(className) : constructor_1.createPrototypeName(className);
const feature = isStatic ? lualib_1.LuaLibFeature.ObjectDefineProperty : lualib_1.LuaLibFeature.SetDescriptor;
const parameters = [target, propertyName, descriptor];
if (!isStatic)
parameters.push(lua.createBooleanLiteral(true));
const call = lualib_1.transformLuaLibFunction(context, feature, undefined, ...parameters);
return lua.createExpressionStatement(call);

@@ -42,0 +38,0 @@ }

import * as ts from "typescript";
import * as lua from "../../../../LuaAST";
import { TransformationContext } from "../../../context";
export declare function createPrototypeName(className: lua.Identifier): lua.TableIndexExpression;
export declare function createConstructorName(className: lua.Identifier): lua.TableIndexExpression;
export declare function transformConstructorDeclaration(context: TransformationContext, statement: ts.ConstructorDeclaration, className: lua.Identifier, instanceFields: ts.PropertyDeclaration[], classDeclaration: ts.ClassLikeDeclaration): lua.Statement | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformConstructorDeclaration = exports.createConstructorName = void 0;
exports.transformConstructorDeclaration = exports.createConstructorName = exports.createPrototypeName = void 0;
const ts = require("typescript");

@@ -11,4 +11,8 @@ const lua = require("../../../../LuaAST");

const fields_1 = require("./fields");
function createPrototypeName(className) {
return lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype"));
}
exports.createPrototypeName = createPrototypeName;
function createConstructorName(className) {
return lua.createTableIndexExpression(lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), lua.createStringLiteral("____constructor"));
return lua.createTableIndexExpression(createPrototypeName(className), lua.createStringLiteral("____constructor"));
}

@@ -23,3 +27,3 @@ exports.createConstructorName = createConstructorName;

const scope = scope_1.pushScope(context, scope_1.ScopeType.Function);
const body = function_1.transformFunctionBodyStatements(context, statement.body);
const body = function_1.transformFunctionBodyContent(context, statement.body);
const [params, dotsLiteral, restParamName] = function_1.transformParameters(context, statement.parameters, lua_ast_1.createSelfIdentifier());

@@ -26,0 +30,0 @@ // Make sure default parameters are assigned before fields are initialized

import * as ts from "typescript";
import * as lua from "../../../../LuaAST";
import { TransformationContext } from "../../../context";
export declare function createPropertyDecoratingExpression(context: TransformationContext, node: ts.PropertyDeclaration | ts.AccessorDeclaration, className: lua.Identifier, noPrototype: boolean): lua.Expression | undefined;
export declare function transformClassInstanceFields(context: TransformationContext, classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[]): lua.Statement[];
export declare function transformStaticPropertyDeclaration(context: TransformationContext, field: ts.PropertyDeclaration, className: lua.Identifier): lua.AssignmentStatement | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformClassInstanceFields = void 0;
exports.transformStaticPropertyDeclaration = exports.transformClassInstanceFields = exports.createPropertyDecoratingExpression = void 0;
const ts = require("typescript");

@@ -9,2 +9,12 @@ const lua = require("../../../../LuaAST");

const accessors_1 = require("./accessors");
const decorators_1 = require("../decorators");
const method_1 = require("./method");
function createPropertyDecoratingExpression(context, node, className, noPrototype) {
if (!node.decorators)
return;
const propertyName = literal_1.transformPropertyName(context, node.name);
const propertyOwnerTable = method_1.transformMemberExpressionOwnerName(node, className, noPrototype);
return decorators_1.createDecoratingExpression(context, node.kind, node.decorators.map(d => decorators_1.transformDecoratorExpression(context, d)), propertyOwnerTable, propertyName);
}
exports.createPropertyDecoratingExpression = createPropertyDecoratingExpression;
function transformClassInstanceFields(context, classDeclaration, instanceFields) {

@@ -37,2 +47,11 @@ var _a;

exports.transformClassInstanceFields = transformClassInstanceFields;
function transformStaticPropertyDeclaration(context, field, className) {
if (!field.initializer)
return;
const fieldName = literal_1.transformPropertyName(context, field.name);
const value = context.transformExpression(field.initializer);
const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName);
return lua.createAssignmentStatement(classField, value);
}
exports.transformStaticPropertyDeclaration = transformStaticPropertyDeclaration;
//# sourceMappingURL=fields.js.map
import * as ts from "typescript";
import * as lua from "../../../../LuaAST";
import { TransformationContext } from "../../../context";
export declare function transformMemberExpressionOwnerName(node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, className: lua.Identifier, noPrototype: boolean): lua.Expression;
export declare function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression;
export declare function transformMethodDeclaration(context: TransformationContext, node: ts.MethodDeclaration, className: lua.Identifier, noPrototype: boolean): lua.Statement | undefined;
export declare function createMethodDecoratingExpression(context: TransformationContext, node: ts.MethodDeclaration, className: lua.Identifier, noPrototype: boolean): lua.Statement | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformMethodDeclaration = void 0;
exports.createMethodDecoratingExpression = exports.transformMethodDeclaration = exports.transformMethodName = exports.transformMemberExpressionOwnerName = void 0;
const lua = require("../../../../LuaAST");

@@ -8,14 +8,24 @@ const function_1 = require("../../function");

const utils_1 = require("../utils");
const decorators_1 = require("../decorators");
const constructor_1 = require("./constructor");
const lualib_1 = require("../../../utils/lualib");
const utils_2 = require("../../../../utils");
function transformMemberExpressionOwnerName(node, className, noPrototype) {
return utils_1.isStaticNode(node) || noPrototype ? lua.cloneIdentifier(className) : constructor_1.createPrototypeName(className);
}
exports.transformMemberExpressionOwnerName = transformMemberExpressionOwnerName;
function transformMethodName(context, node) {
const methodName = literal_1.transformPropertyName(context, node.name);
if (lua.isStringLiteral(methodName) && methodName.value === "toString") {
return lua.createStringLiteral("__tostring", node.name);
}
return methodName;
}
exports.transformMethodName = transformMethodName;
function transformMethodDeclaration(context, node, className, noPrototype) {
// Don't transform methods without body (overload declarations)
if (!node.body) {
return undefined;
}
const methodTable = utils_1.isStaticNode(node) || noPrototype
? lua.cloneIdentifier(className)
: lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype"));
let methodName = literal_1.transformPropertyName(context, node.name);
if (lua.isStringLiteral(methodName) && methodName.value === "toString") {
methodName = lua.createStringLiteral("__tostring", node.name);
}
if (!node.body)
return;
const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype);
const methodName = transformMethodName(context, node);
const [functionExpression] = function_1.transformFunctionToExpression(context, node);

@@ -25,2 +35,16 @@ return lua.createAssignmentStatement(lua.createTableIndexExpression(methodTable, methodName), functionExpression, node);

exports.transformMethodDeclaration = transformMethodDeclaration;
function createMethodDecoratingExpression(context, node, className, noPrototype) {
var _a, _b;
const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype);
const methodName = transformMethodName(context, node);
const parameterDecorators = node.parameters
.flatMap((parameter, index) => { var _a; return (_a = parameter.decorators) === null || _a === void 0 ? void 0 : _a.map(decorator => lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.DecorateParam, node, lua.createNumericLiteral(index), decorators_1.transformDecoratorExpression(context, decorator))); })
.filter(utils_2.isNonNull);
const methodDecorators = (_b = (_a = node.decorators) === null || _a === void 0 ? void 0 : _a.map(d => decorators_1.transformDecoratorExpression(context, d))) !== null && _b !== void 0 ? _b : [];
if (methodDecorators.length > 0 || parameterDecorators.length > 0) {
const decorateMethod = decorators_1.createDecoratingExpression(context, node.kind, [...methodDecorators, ...parameterDecorators], methodTable, methodName);
return lua.createExpressionStatement(decorateMethod);
}
}
exports.createMethodDecoratingExpression = createMethodDecoratingExpression;
//# sourceMappingURL=method.js.map
import * as ts from "typescript";
import * as lua from "../../LuaAST";
import { FunctionVisitor, TransformationContext } from "../context";
import { FunctionVisitor } from "../context";
export declare const transformDeleteExpression: FunctionVisitor<ts.DeleteExpression>;
export declare function transformDeleteExpressionStatement(context: TransformationContext, node: ts.ExpressionStatement): lua.Statement | undefined;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformDeleteExpressionStatement = exports.transformDeleteExpression = void 0;
exports.transformDeleteExpression = void 0;
const ts = require("typescript");
const lua = require("../../LuaAST");
const utils_1 = require("../../utils");
const lualib_1 = require("../utils/lualib");
const diagnostics_1 = require("../utils/diagnostics");
const typescript_1 = require("../utils/typescript");
const lua_ast_1 = require("../utils/lua-ast");
exports.transformDeleteExpression = (node, context) => {
const lhs = utils_1.cast(context.transformExpression(node.expression), lua.isAssignmentLeftHandSideExpression);
const assignment = lua.createAssignmentStatement(lhs, lua.createNilLiteral(), node);
return lua_ast_1.createImmediatelyInvokedFunctionExpression([assignment], [lua.createBooleanLiteral(true)], node);
let ownerExpression;
let propertyExpression;
if (ts.isPropertyAccessExpression(node.expression)) {
if (ts.isPrivateIdentifier(node.expression.name))
throw new Error("PrivateIdentifier is not supported");
ownerExpression = context.transformExpression(node.expression.expression);
propertyExpression = lua.createStringLiteral(node.expression.name.text);
}
else if (ts.isElementAccessExpression(node.expression)) {
ownerExpression = context.transformExpression(node.expression.expression);
propertyExpression = context.transformExpression(node.expression.argumentExpression);
const type = context.checker.getTypeAtLocation(node.expression.expression);
const argumentType = context.checker.getTypeAtLocation(node.expression.argumentExpression);
if (typescript_1.isArrayType(context, type) && typescript_1.isNumberType(context, argumentType)) {
propertyExpression = lua_ast_1.addToNumericExpression(propertyExpression, 1);
}
}
if (!ownerExpression || !propertyExpression) {
context.diagnostics.push(diagnostics_1.unsupportedProperty(node, "delete", ts.SyntaxKind[node.kind]));
return lua.createNilLiteral();
}
return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Delete, node, ownerExpression, propertyExpression);
};
function transformDeleteExpressionStatement(context, node) {
const expression = ts.isExpressionStatement(node) ? node.expression : node;
if (ts.isDeleteExpression(expression)) {
return lua.createAssignmentStatement(utils_1.cast(context.transformExpression(expression.expression), lua.isAssignmentLeftHandSideExpression), lua.createNilLiteral(), expression);
}
}
exports.transformDeleteExpressionStatement = transformDeleteExpressionStatement;
//# sourceMappingURL=delete.js.map

@@ -7,3 +7,2 @@ "use strict";

const binary_expression_1 = require("./binary-expression");
const delete_1 = require("./delete");
const lua_table_1 = require("./lua-table");

@@ -24,6 +23,2 @@ const unary_expression_1 = require("./unary-expression");

}
const deleteExpressionResult = delete_1.transformDeleteExpressionStatement(context, node);
if (deleteExpressionResult) {
return deleteExpressionResult;
}
const expression = ts.isExpressionStatement(node) ? node.expression : node;

@@ -30,0 +25,0 @@ const result = context.transformExpression(expression);

@@ -5,5 +5,5 @@ import * as ts from "typescript";

import { Scope } from "../utils/scope";
export declare function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[];
export declare function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[];
export declare function transformFunctionBodyHeader(context: TransformationContext, bodyScope: Scope, parameters: ts.NodeArray<ts.ParameterDeclaration>, spreadIdentifier?: lua.Identifier): lua.Statement[];
export declare function transformFunctionBody(context: TransformationContext, parameters: ts.NodeArray<ts.ParameterDeclaration>, body: ts.Block, spreadIdentifier?: lua.Identifier): [lua.Statement[], Scope];
export declare function transformFunctionBody(context: TransformationContext, parameters: ts.NodeArray<ts.ParameterDeclaration>, body: ts.ConciseBody, spreadIdentifier?: lua.Identifier): [lua.Statement[], Scope];
export declare function transformParameters(context: TransformationContext, parameters: ts.NodeArray<ts.ParameterDeclaration>, functionContext?: lua.Identifier): [lua.Identifier[], lua.DotsLiteral | undefined, lua.Identifier | undefined];

@@ -10,0 +10,0 @@ export declare function transformFunctionToExpression(context: TransformationContext, node: ts.FunctionLikeDeclaration): [lua.Expression, Scope];

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformYieldExpression = exports.transformFunctionDeclaration = exports.transformFunctionLikeDeclaration = exports.transformFunctionToExpression = exports.transformParameters = exports.transformFunctionBody = exports.transformFunctionBodyHeader = exports.transformFunctionBodyStatements = void 0;
exports.transformYieldExpression = exports.transformFunctionDeclaration = exports.transformFunctionLikeDeclaration = exports.transformFunctionToExpression = exports.transformParameters = exports.transformFunctionBody = exports.transformFunctionBodyHeader = exports.transformFunctionBodyContent = void 0;
const ts = require("typescript");

@@ -14,2 +14,3 @@ const lua = require("../../LuaAST");

const identifier_1 = require("./identifier");
const return_1 = require("./return");
const variable_declaration_1 = require("./variable-declaration");

@@ -37,7 +38,11 @@ function transformParameterDefaultValueDeclaration(context, parameterName, value, tsOriginal) {

}
function transformFunctionBodyStatements(context, body) {
function transformFunctionBodyContent(context, body) {
if (!ts.isBlock(body)) {
const returnStatement = return_1.transformExpressionBodyToReturnStatement(context, body);
return [returnStatement];
}
const bodyStatements = scope_1.performHoisting(context, context.transformStatements(body.statements));
return bodyStatements;
}
exports.transformFunctionBodyStatements = transformFunctionBodyStatements;
exports.transformFunctionBodyContent = transformFunctionBodyContent;
function transformFunctionBodyHeader(context, bodyScope, parameters, spreadIdentifier) {

@@ -75,3 +80,3 @@ const headerStatements = [];

const scope = scope_1.pushScope(context, scope_1.ScopeType.Function);
const bodyStatements = transformFunctionBodyStatements(context, body);
const bodyStatements = transformFunctionBodyContent(context, body);
const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier);

@@ -136,15 +141,4 @@ scope_1.popScope(context);

}
let body;
if (ts.isBlock(node.body)) {
body = node.body;
}
else {
const returnExpression = ts.createReturn(node.body);
body = ts.createBlock([returnExpression]);
returnExpression.parent = body;
if (node.body)
body.parent = node.body.parent;
}
const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext);
const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier);
const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, node.body, spreadIdentifier);
const functionExpression = lua.createFunctionExpression(lua.createBlock(transformedBody), paramNames, dotsLiteral, flags, node);

@@ -204,3 +198,8 @@ return [

};
exports.transformYieldExpression = (expression, context) => lua.createCallExpression(lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), expression.expression ? [context.transformExpression(expression.expression)] : [], expression);
exports.transformYieldExpression = (expression, context) => {
const parameters = expression.expression ? [context.transformExpression(expression.expression)] : [];
return expression.asteriskToken
? lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.DelegatedYield, expression, ...parameters)
: lua.createCallExpression(lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), parameters, expression);
};
//# sourceMappingURL=function.js.map
import * as ts from "typescript";
import { FunctionVisitor } from "../context";
import * as lua from "../../LuaAST";
import { FunctionVisitor, TransformationContext } from "../context";
export declare function transformExpressionBodyToReturnStatement(context: TransformationContext, node: ts.Expression): lua.Statement;
export declare const transformReturnStatement: FunctionVisitor<ts.ReturnStatement>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformReturnStatement = void 0;
exports.transformReturnStatement = exports.transformExpressionBodyToReturnStatement = void 0;
const ts = require("typescript");

@@ -11,2 +11,31 @@ const lua = require("../../LuaAST");

const typescript_1 = require("../utils/typescript");
function transformExpressionsInReturn(context, node, insideTryCatch) {
if (!annotations_1.isInTupleReturnFunction(context, node)) {
return [context.transformExpression(node)];
}
let results;
const expressionType = context.checker.getTypeAtLocation(node);
// Parent function is a TupleReturn function
if (ts.isArrayLiteralExpression(node)) {
// If return expression is an array literal, leave out brackets.
results = node.elements.map(e => context.transformExpression(e));
}
else if (!annotations_1.isTupleReturnCall(context, node) && typescript_1.isArrayType(context, expressionType)) {
// If return expression is an array-type and not another TupleReturn call, unpack it
results = [lua_ast_1.createUnpackCall(context, context.transformExpression(node), node)];
}
else {
results = [context.transformExpression(node)];
}
// Wrap tupleReturn results when returning inside try/catch
if (insideTryCatch) {
results = [lua_ast_1.wrapInTable(...results)];
}
return results;
}
function transformExpressionBodyToReturnStatement(context, node) {
const expressions = transformExpressionsInReturn(context, node, false);
return lua.createReturnStatement(expressions, node);
}
exports.transformExpressionBodyToReturnStatement = transformExpressionBodyToReturnStatement;
exports.transformReturnStatement = (statement, context) => {

@@ -29,25 +58,3 @@ // Bubble up explicit return flag and check if we're inside a try/catch block

}
if (annotations_1.isInTupleReturnFunction(context, statement)) {
// Parent function is a TupleReturn function
if (ts.isArrayLiteralExpression(statement.expression)) {
// If return expression is an array literal, leave out brackets.
results = statement.expression.elements.map(e => context.transformExpression(e));
}
else if (!annotations_1.isTupleReturnCall(context, statement.expression) && typescript_1.isArrayType(context, expressionType)) {
// If return expression is an array-type and not another TupleReturn call, unpack it
results = [
lua_ast_1.createUnpackCall(context, context.transformExpression(statement.expression), statement.expression),
];
}
else {
results = [context.transformExpression(statement.expression)];
}
// Wrap tupleReturn results when returning inside try/catch
if (insideTryCatch) {
results = [lua_ast_1.wrapInTable(...results)];
}
}
else {
results = [context.transformExpression(statement.expression)];
}
results = transformExpressionsInReturn(context, statement.expression, insideTryCatch);
}

@@ -54,0 +61,0 @@ else {

@@ -8,5 +8,7 @@ "use strict";

const lua_ast_1 = require("../utils/lua-ast");
const lualib_1 = require("../utils/lualib");
const scope_1 = require("../utils/scope");
const typescript_1 = require("../utils/typescript");
exports.transformSourceFileNode = (node, context) => {
var _a, _b;
let statements = [];

@@ -40,4 +42,5 @@ if (node.flags & ts.NodeFlags.JsonFile) {

}
return lua.createBlock(statements, node);
const trivia = (_b = (_a = node.getFullText().match(/^#!.*\r?\n/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "";
return lua.createFile(statements, lualib_1.getUsedLuaLibFeatures(context), trivia, node);
};
//# sourceMappingURL=sourceFile.js.map

@@ -10,4 +10,4 @@ "use strict";

var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
}
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -14,0 +14,0 @@ exports.transpileString = exports.transpileVirtualProject = exports.createVirtualProgram = exports.transpileProject = exports.transpileFiles = void 0;

@@ -43,9 +43,9 @@ "use strict";

const processSourceFile = (sourceFile) => {
const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformation_1.transformSourceFile(program, sourceFile, visitorMap);
const { file, diagnostics: transformDiagnostics } = transformation_1.transformSourceFile(program, sourceFile, visitorMap);
diagnostics.push(...transformDiagnostics);
if (!options.noEmit && !options.emitDeclarationOnly) {
const printResult = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures);
const printResult = printer(program, emitHost, sourceFile.fileName, file);
const sourceRootDir = program.getCommonSourceDirectory();
const fileName = path.resolve(sourceRootDir, sourceFile.fileName);
transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst, ...printResult });
transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst: file, ...printResult });
}

@@ -52,0 +52,0 @@ };

@@ -15,3 +15,3 @@ import * as ts from "typescript";

fileName: string;
luaAst?: lua.Block;
luaAst?: lua.File;
}

@@ -18,0 +18,0 @@ export interface EmitFile extends BaseFile {

{
"name": "typescript-to-lua",
"version": "0.35.0",
"version": "0.36.0",
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",

@@ -41,3 +41,3 @@ "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",

"source-map": "^0.7.3",
"typescript": "^3.9.2"
"typescript": ">=4.0.2"
},

@@ -51,3 +51,3 @@ "devDependencies": {

"@typescript-eslint/eslint-plugin": "^2.31.0",
"@typescript-eslint/parser": "^2.31.0",
"@typescript-eslint/parser": "^4.1.0",
"eslint": "^6.8.0",

@@ -63,5 +63,5 @@ "eslint-plugin-import": "^2.20.1",

"prettier": "^2.0.5",
"ts-jest": "^26.0.0",
"ts-jest": "^26.3.0",
"ts-node": "^8.6.2"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc