Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

typescript-to-lua

Package Overview
Dependencies
Maintainers
2
Versions
158
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.16.1 to 0.17.0

dist/lualib/ArrayFlat.lua

8

CHANGELOG.md

@@ -5,3 +5,3 @@ # Changelog

* **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument.
* To remove the self parameter from a single function add `this: void` to its declaration:
* To remove the self parameter from a single function add `this: void` to its declaration:
```declare function foo(this: void, ...)```

@@ -13,3 +13,3 @@ * To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`:

---
* **BREAKING CHANGE:** Directive `/** @luaIterator */` should now be put on types instead of on the functions returning them.

@@ -87,3 +87,3 @@

## 0.13.0
* Reworked how functions are transpiled, see https://github.com/Perryvw/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods
* Reworked how functions are transpiled, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods
* Improved handling of types extending Array.

@@ -95,3 +95,3 @@ * Fixed several bugs with classes.

* Added detection of types extending Array.
* Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/Perryvw/TypescriptToLua/wiki/Compiler-Directives
* Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Compiler-Directives
* Fixed bug with constructor default values.

@@ -98,0 +98,0 @@ * The Lualib is no longer included when not used.

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

},
sourceMapTraceback: {
default: false,
describe: "Applies the source map to show source TS files and lines in error tracebacks.",
type: "boolean",
},
};

@@ -33,0 +38,0 @@ exports.version = require("../package.json").version;

import * as ts from "typescript";
import { CompilerOptions } from "./CompilerOptions";
import { TranspileResult } from "./LuaTranspiler";
export declare function compile(argv: string[]): void;

@@ -11,2 +12,2 @@ export declare function watchWithOptions(fileNames: string[], options: CompilerOptions): void;

[filename: string]: string;
}, options?: CompilerOptions, ignoreDiagnostics?: boolean, filePath?: string): string;
}, options?: CompilerOptions, ignoreDiagnostics?: boolean, filePath?: string): TranspileResult;

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

getCurrentDirectory: () => "",
getDefaultLibFileName: () => "lib.es6.d.ts",
getDefaultLibFileName: ts.getDefaultLibFileName,
getDirectories: () => [],

@@ -129,15 +129,10 @@ getNewLine: () => "\n",

}
if (filename.indexOf(".d.ts") !== -1) {
if (!libCache[filename]) {
const typeScriptDir = path.dirname(require.resolve("typescript"));
const filePath = path.join(typeScriptDir, filename);
if (fs.existsSync(filePath)) {
libCache[filename] = fs.readFileSync(filePath).toString();
}
else {
const pathWithLibPrefix = path.join(typeScriptDir, "lib." + filename);
libCache[filename] = fs.readFileSync(pathWithLibPrefix).toString();
}
}
return ts.createSourceFile(filename, libCache[filename], ts.ScriptTarget.Latest, false);
if (filename.startsWith('lib.')) {
if (libCache[filename])
return libCache[filename];
const typeScriptDir = path.dirname(require.resolve("typescript"));
const filePath = path.join(typeScriptDir, filename);
const content = fs.readFileSync(filePath, 'utf8');
libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false);
return libCache[filename];
}

@@ -166,6 +161,5 @@ return undefined;

const transpiler = new LuaTranspiler_1.LuaTranspiler(program);
const result = transpiler.transpileSourceFile(program.getSourceFile(filePath));
return result.trim();
return transpiler.transpileSourceFile(program.getSourceFile(filePath));
}
exports.transpileString = transpileString;
//# sourceMappingURL=Compiler.js.map

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

noHoisting?: boolean;
sourceMapTraceback?: boolean;
}

@@ -9,0 +10,0 @@ export declare enum LuaLibImportKind {

export { parseCommandLine } from "./CommandLineParser";
export { compile, compileFilesWithOptions, transpileString, watchWithOptions } from "./Compiler";
export { CompilerOptions, LuaLibImportKind, LuaTarget, } from "./CompilerOptions";
export { LuaLibFeature, } from "./LuaLib";
export { LuaTranspiler, } from "./LuaTranspiler";
export { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions";
export { LuaLibFeature } from "./LuaLib";
export { LuaTranspiler } from "./LuaTranspiler";

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

export interface TextRange {
pos: number;
end: number;
line?: number;
column?: number;
}

@@ -78,2 +78,3 @@ export interface Node extends TextRange {

export declare function setParent(node: Node | Node[] | undefined, parent: Node): void;
export declare function getOriginalPos(node: Node): TextRange;
export interface Block extends Node {

@@ -272,3 +273,3 @@ kind: SyntaxKind.Block;

export declare function createIdentifier(text: string | ts.__String, tsOriginal?: ts.Node, symbolId?: SymbolId, parent?: Node): Identifier;
export declare function cloneIdentifier(identifier: Identifier): Identifier;
export declare function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): Identifier;
export declare function createAnnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier;

@@ -275,0 +276,0 @@ export interface TableIndexExpression extends Expression {

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

Object.defineProperty(exports, "__esModule", { value: true });
// We can ellide a lot of nodes especially tokens and keyowords
// becasue we dont create the AST from text
const ts = require("typescript");
var SyntaxKind;

@@ -75,9 +78,9 @@ (function (SyntaxKind) {

function createNode(kind, tsOriginal, parent) {
let pos = -1;
let end = -1;
if (tsOriginal) {
pos = tsOriginal.pos;
end = tsOriginal.end;
const sourcePosition = getSourcePosition(tsOriginal);
if (sourcePosition) {
return { kind, parent, line: sourcePosition.line, column: sourcePosition.column };
}
return { kind, parent, pos, end };
else {
return { kind, parent };
}
}

@@ -90,4 +93,7 @@ exports.createNode = createNode;

function setNodeOriginal(node, tsOriginal) {
node.pos = tsOriginal.pos;
node.end = tsOriginal.end;
const sourcePosition = getSourcePosition(tsOriginal);
if (sourcePosition) {
node.line = sourcePosition.line;
node.column = sourcePosition.column;
}
return node;

@@ -103,6 +109,2 @@ }

n.parent = parent;
if (n.pos === -1 || n.end === -1) {
n.pos = parent.pos;
n.end = parent.end;
}
});

@@ -112,9 +114,18 @@ }

node.parent = parent;
if (node.pos === -1 || node.end === -1) {
node.pos = parent.pos;
node.end = parent.end;
}
}
}
exports.setParent = setParent;
function getSourcePosition(sourceNode) {
if (sourceNode !== undefined && sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) {
const { line, character } = ts.getLineAndCharacterOfPosition(sourceNode.getSourceFile(), sourceNode.pos + sourceNode.getLeadingTriviaWidth());
return { line, column: character };
}
}
function getOriginalPos(node) {
while (node.line === undefined && node.parent !== undefined) {
node = node.parent;
}
return { line: node.line, column: node.column };
}
exports.getOriginalPos = getOriginalPos;
function isBlock(node) {

@@ -484,4 +495,4 @@ return node.kind === SyntaxKind.Block;

exports.createIdentifier = createIdentifier;
function cloneIdentifier(identifier) {
return createIdentifier(identifier.text, undefined, identifier.symbolId);
function cloneIdentifier(identifier, tsOriginal) {
return createIdentifier(identifier.text, tsOriginal, identifier.symbolId);
}

@@ -488,0 +499,0 @@ exports.cloneIdentifier = cloneIdentifier;

@@ -17,2 +17,4 @@ export declare enum LuaLibFeature {

ArraySplice = "ArraySplice",
ArrayFlat = "ArrayFlat",
ArrayFlatMap = "ArrayFlatMap",
ClassIndex = "ClassIndex",

@@ -30,2 +32,3 @@ ClassNewIndex = "ClassNewIndex",

ObjectEntries = "ObjectEntries",
ObjectFromEntries = "ObjectFromEntries",
ObjectKeys = "ObjectKeys",

@@ -36,2 +39,3 @@ ObjectValues = "ObjectValues",

WeakSet = "WeakSet",
SourceMapTraceBack = "SourceMapTraceBack",
StringReplace = "StringReplace",

@@ -38,0 +42,0 @@ StringSplit = "StringSplit",

@@ -22,2 +22,4 @@ "use strict";

LuaLibFeature["ArraySplice"] = "ArraySplice";
LuaLibFeature["ArrayFlat"] = "ArrayFlat";
LuaLibFeature["ArrayFlatMap"] = "ArrayFlatMap";
LuaLibFeature["ClassIndex"] = "ClassIndex";

@@ -35,2 +37,3 @@ LuaLibFeature["ClassNewIndex"] = "ClassNewIndex";

LuaLibFeature["ObjectEntries"] = "ObjectEntries";
LuaLibFeature["ObjectFromEntries"] = "ObjectFromEntries";
LuaLibFeature["ObjectKeys"] = "ObjectKeys";

@@ -41,2 +44,3 @@ LuaLibFeature["ObjectValues"] = "ObjectValues";

LuaLibFeature["WeakSet"] = "WeakSet";
LuaLibFeature["SourceMapTraceBack"] = "SourceMapTraceBack";
LuaLibFeature["StringReplace"] = "StringReplace";

@@ -49,3 +53,6 @@ LuaLibFeature["StringSplit"] = "StringSplit";

const luaLibDependencies = {
ArrayFlat: [LuaLibFeature.ArrayConcat],
ArrayFlatMap: [LuaLibFeature.ArrayConcat],
Iterator: [LuaLibFeature.Symbol],
ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol],
Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol],

@@ -52,0 +59,0 @@ Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol],

import * as tstl from "./LuaAST";
import { CompilerOptions } from "./CompilerOptions";
import { LuaLibFeature } from "./LuaLib";
import { CompilerOptions } from "./CompilerOptions";
export declare class LuaPrinter {

@@ -8,7 +8,13 @@ private static operatorMap;

private currentIndent;
private sourceFile;
constructor(options: CompilerOptions);
print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>): string;
print(block: tstl.Block, luaLibFeatures?: Set<LuaLibFeature>, sourceFile?: string): [string, string];
private printInlineSourceMap;
private printStackTraceOverride;
private printImplementation;
private pushIndent;
private popIndent;
private indent;
private createSourceNode;
private concatNodes;
private printBlock;

@@ -48,2 +54,3 @@ private printStatement;

private ignoreDeadStatements;
private joinChunks;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const source_map_1 = require("source-map");
const tstl = require("./LuaAST");
const CompilerOptions_1 = require("./CompilerOptions");
const LuaLib_1 = require("./LuaLib");
const TSHelper_1 = require("./TSHelper");
const LuaLib_1 = require("./LuaLib");
const CompilerOptions_1 = require("./CompilerOptions");
class LuaPrinter {

@@ -12,6 +14,54 @@ constructor(options) {

}
print(block, luaLibFeatures) {
print(block, luaLibFeatures, sourceFile) {
// Add traceback lualib if sourcemap traceback option is enabled
if (this.options.sourceMapTraceback) {
if (luaLibFeatures === undefined) {
luaLibFeatures = new Set();
}
luaLibFeatures.add(LuaLib_1.LuaLibFeature.SourceMapTraceBack);
}
const rootSourceNode = this.printImplementation(block, luaLibFeatures, sourceFile);
const codeWithSourceMap = rootSourceNode
// TODO is the file: part really required? and should this be handled in the printer?
.toStringWithSourceMap({ file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua" });
let codeResult = codeWithSourceMap.code;
if (this.options.inlineSourceMap) {
codeResult += "\n" + this.printInlineSourceMap(codeWithSourceMap.map);
}
if (this.options.sourceMapTraceback) {
const stackTraceOverride = this.printStackTraceOverride(rootSourceNode);
codeResult = codeResult.replace("{#SourceMapTraceback}", stackTraceOverride);
}
return [codeResult, codeWithSourceMap.map.toString()];
}
printInlineSourceMap(sourceMap) {
const map = sourceMap.toString();
const base64Map = Buffer.from(map).toString('base64');
return `//# sourceMappingURL=data:application/json;base64,${base64Map}\n`;
}
printStackTraceOverride(rootNode) {
let line = 1;
const map = {};
rootNode.walk((chunk, mappedPosition) => {
if (mappedPosition.line !== undefined && mappedPosition.line > 0) {
if (map[line] === undefined) {
map[line] = mappedPosition.line;
}
else {
map[line] = Math.min(map[line], mappedPosition.line);
}
}
line += chunk.split("\n").length - 1;
});
const mapItems = [];
for (const lineNr in map) {
mapItems.push(`["${lineNr}"] = ${map[lineNr]}`);
}
const mapString = "{" + mapItems.join(",") + "}";
return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`;
}
printImplementation(block, luaLibFeatures, sourceFile) {
let header = "";
if (this.options.noHeader === undefined || this.options.noHeader === false) {
header += `--[[ Generated with https://github.com/Perryvw/TypescriptToLua ]]\n`;
header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`;
}

@@ -30,3 +80,8 @@ if (luaLibFeatures) {

}
return header + this.printBlock(block);
this.sourceFile = path.basename(sourceFile);
if (this.options.sourceMapTraceback) {
header += "{#SourceMapTraceback}\n";
}
const fileBlockNode = this.createSourceNode(block, this.printBlock(block));
return this.concatNodes(header, fileBlockNode);
}

@@ -39,7 +94,16 @@ pushIndent() {

}
indent(input) {
return this.currentIndent + input;
indent(input = "") {
return this.concatNodes(this.currentIndent, input);
}
createSourceNode(node, chunks) {
const originalPos = tstl.getOriginalPos(node);
return originalPos !== undefined
? new source_map_1.SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks)
: new source_map_1.SourceNode(undefined, undefined, this.sourceFile, chunks);
}
concatNodes(...chunks) {
return new source_map_1.SourceNode(undefined, undefined, this.sourceFile, chunks);
}
printBlock(block) {
return this.ignoreDeadStatements(block.statements).map(s => this.printStatement(s)).join("");
return this.createSourceNode(block, this.ignoreDeadStatements(block.statements).map(s => this.printStatement(s)));
}

@@ -74,63 +138,76 @@ printStatement(statement) {

return this.printExpressionStatement(statement);
default:
throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[statement.kind]}`);
}
}
printDoStatement(statement) {
let result = this.indent("do\n");
const chunks = [];
chunks.push(this.indent("do\n"));
this.pushIndent();
result += this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s)).join("");
chunks.push(...this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s)));
this.popIndent();
result += this.indent("end\n");
return result;
chunks.push(this.indent("end\n"));
return this.concatNodes(...chunks);
}
printVariableDeclarationStatement(statement) {
const left = this.indent(`local ${statement.left.map(e => this.printExpression(e)).join(", ")}`);
const chunks = [];
chunks.push(this.indent("local "));
chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e))));
if (statement.right) {
return left + ` = ${statement.right.map(e => this.printExpression(e)).join(", ")};\n`;
chunks.push(" = ");
chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e))));
}
else {
return left + ";\n";
}
chunks.push(";\n");
return this.concatNodes(...chunks);
}
printVariableAssignmentStatement(statement) {
return this.indent(`${statement.left.map(e => this.printExpression(e)).join(", ")} = ` +
`${statement.right.map(e => this.printExpression(e)).join(", ")};\n`);
const chunks = [];
chunks.push(this.indent());
chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e))));
chunks.push(" = ");
chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e))));
chunks.push(";\n");
return this.createSourceNode(statement, chunks);
}
printIfStatement(statement, isElseIf) {
const chunks = [];
const prefix = isElseIf ? "elseif" : "if";
let result = this.indent(`${prefix} ${this.printExpression(statement.condtion)} then\n`);
chunks.push(this.indent(prefix + " "), this.printExpression(statement.condtion), " then\n");
this.pushIndent();
result += this.printBlock(statement.ifBlock);
chunks.push(this.printBlock(statement.ifBlock));
this.popIndent();
if (statement.elseBlock) {
if (tstl.isIfStatement(statement.elseBlock)) {
result += this.printIfStatement(statement.elseBlock, true);
chunks.push(this.printIfStatement(statement.elseBlock, true));
}
else {
result += this.indent("else\n");
chunks.push(this.indent("else\n"));
this.pushIndent();
result += this.printBlock(statement.elseBlock);
chunks.push(this.printBlock(statement.elseBlock));
this.popIndent();
result += this.indent("end\n");
chunks.push(this.indent("end\n"));
}
}
else {
result += this.indent("end\n");
chunks.push(this.indent("end\n"));
}
return result;
return this.concatNodes(...chunks);
}
printWhileStatement(statement) {
let result = this.indent(`while ${this.printExpression(statement.condtion)} do\n`);
const chunks = [];
chunks.push(this.indent("while "), this.printExpression(statement.condtion), " do\n");
this.pushIndent();
result += this.printBlock(statement.body);
chunks.push(this.printBlock(statement.body));
this.popIndent();
result += this.indent("end\n");
return result;
chunks.push(this.indent("end\n"));
return this.concatNodes(...chunks);
}
printRepeatStatement(statement) {
let result = this.indent(`repeat\n`);
const chunks = [];
chunks.push(this.indent(`repeat\n`));
this.pushIndent();
result += this.printBlock(statement.body);
chunks.push(this.printBlock(statement.body));
this.popIndent();
result += this.indent(`until ${this.printExpression(statement.condtion)};\n`);
return result;
chunks.push(this.indent("until "), this.printExpression(statement.condtion), ";\n");
return this.concatNodes(...chunks);
}

@@ -141,13 +218,13 @@ printForStatement(statement) {

const limit = this.printExpression(statement.limitExpression);
let result = this.indent(`for ${ctrlVar} = ${ctrlVarInit}, ${limit}`);
const chunks = [];
chunks.push(this.indent("for "), ctrlVar, " = ", ctrlVarInit, ", ", limit);
if (statement.stepExpression) {
const step = this.printExpression(statement.stepExpression);
result += `, ${step}`;
chunks.push(", ", this.printExpression(statement.stepExpression));
}
result += ` do\n`;
chunks.push(" do\n");
this.pushIndent();
result += this.printBlock(statement.body);
chunks.push(this.printBlock(statement.body));
this.popIndent();
result += this.indent("end\n");
return result;
chunks.push(this.indent("end\n"));
return this.concatNodes(...chunks);
}

@@ -157,26 +234,30 @@ printForInStatement(statement) {

const expressions = statement.expressions.map(e => this.printExpression(e)).join(", ");
let result = this.indent(`for ${names} in ${expressions} do\n`);
const chunks = [];
chunks.push(this.indent("for "), names, " in ", expressions, " do\n");
this.pushIndent();
result += this.printBlock(statement.body);
chunks.push(this.printBlock(statement.body));
this.popIndent();
result += this.indent("end\n");
return result;
chunks.push(this.indent("end\n"));
return this.createSourceNode(statement, chunks);
}
printGotoStatement(statement) {
return this.indent(`goto ${statement.label};\n`);
return this.createSourceNode(statement, [this.indent("goto "), statement.label, ";\n"]);
}
printLabelStatement(statement) {
return this.indent(`::${statement.name}::\n`);
return this.createSourceNode(statement, [this.indent("::"), statement.name, "::\n"]);
}
printReturnStatement(statement) {
if (!statement.expressions) {
return this.indent(`return;\n`);
if (!statement.expressions || statement.expressions.length === 0) {
return this.createSourceNode(statement, this.indent("return;\n"));
}
return this.indent(`return ${statement.expressions.map(e => this.printExpression(e)).join(", ")};\n`);
const chunks = [];
chunks.push(...this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e))));
chunks.push(";\n");
return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]);
}
printBreakStatement(statement) {
return this.indent("break;\n");
return this.createSourceNode(statement, this.indent("break;\n"));
}
printExpressionStatement(statement) {
return this.indent(`${this.printExpression(statement.expression)};\n`);
return this.concatNodes(this.indent(), this.printExpression(statement.expression), ";\n");
}

@@ -217,72 +298,102 @@ // Expressions

return this.printTableIndexExpression(expression);
default:
throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[expression.kind]}`);
}
}
printStringLiteral(expression) {
return `"${expression.value}"`;
return this.createSourceNode(expression, `"${expression.value}"`);
}
printNumericLiteral(expression) {
return `${expression.value}`;
return this.createSourceNode(expression, String(expression.value));
}
printNilLiteral(expression) {
return "nil";
return this.createSourceNode(expression, "nil");
}
printDotsLiteral(expression) {
return "...";
return this.createSourceNode(expression, "...");
}
printBooleanLiteral(expression) {
if (expression.kind === tstl.SyntaxKind.TrueKeyword) {
return "true";
return this.createSourceNode(expression, "true");
}
else {
return "false";
return this.createSourceNode(expression, "false");
}
}
printFunctionExpression(expression) {
const paramterArr = expression.params ? expression.params.map(i => this.printIdentifier(i)) : [];
const parameterChunks = expression.params
? expression.params.map(i => this.printIdentifier(i))
: [];
if (expression.dots) {
paramterArr.push(this.printDotsLiteral(expression.dots));
parameterChunks.push(this.printDotsLiteral(expression.dots));
}
let result = `function(${paramterArr.join(", ")})\n`;
const chunks = [];
chunks.push("function(");
chunks.push(...this.joinChunks(", ", parameterChunks));
chunks.push(")\n");
this.pushIndent();
result += this.printBlock(expression.body);
chunks.push(this.printBlock(expression.body));
this.popIndent();
result += this.indent("end");
return result;
chunks.push(this.indent("end"));
return this.createSourceNode(expression, chunks);
}
printTableFieldExpression(expression) {
const chunks = [];
const value = this.printExpression(expression.value);
if (expression.key) {
if (tstl.isStringLiteral(expression.key) && TSHelper_1.TSHelper.isValidLuaIdentifier(expression.key.value)) {
return `${expression.key.value} = ${value}`;
chunks.push(expression.key.value, " = ", value);
}
else {
return `[${this.printExpression(expression.key)}] = ${value}`;
chunks.push("[", this.printExpression(expression.key), "] = ", value);
}
}
else {
return value;
chunks.push(value);
}
return this.createSourceNode(expression, chunks);
}
printTableExpression(expression) {
let fields = "";
const chunks = [];
chunks.push("{");
if (expression.fields) {
fields = expression.fields.map(f => this.printTableFieldExpression(f)).join(", ");
expression.fields.forEach((f, i) => {
if (i < expression.fields.length - 1) {
chunks.push(this.printTableFieldExpression(f), ", ");
}
else {
chunks.push(this.printTableFieldExpression(f));
}
});
}
return `{${fields}}`;
chunks.push("}");
return this.createSourceNode(expression, chunks);
}
printUnaryExpression(expression) {
const operand = this.needsParentheses(expression.operand)
? `(${this.printExpression(expression.operand)})`
: this.printExpression(expression.operand);
return `${this.printOperator(expression.operator)}${operand}`;
const chunks = [];
chunks.push(this.printOperator(expression.operator));
if (this.needsParentheses(expression.operand)) {
chunks.push("(", this.printExpression(expression.operand), ")");
}
else {
chunks.push(this.printExpression(expression.operand));
}
return this.createSourceNode(expression, chunks);
}
printBinaryExpression(expression) {
const left = this.needsParentheses(expression.left)
? `(${this.printExpression(expression.left)})`
: this.printExpression(expression.left);
const right = this.needsParentheses(expression.right)
? `(${this.printExpression(expression.right)})`
: this.printExpression(expression.right);
const operator = this.printOperator(expression.operator);
return `${left} ${operator} ${right}`;
const chunks = [];
if (this.needsParentheses(expression.left)) {
chunks.push("(", this.printExpression(expression.left), ")");
}
else {
chunks.push(this.printExpression(expression.left));
}
chunks.push(" ", this.printOperator(expression.operator), " ");
if (this.needsParentheses(expression.right)) {
chunks.push("(", this.printExpression(expression.right), ")");
}
else {
chunks.push(this.printExpression(expression.right));
}
return this.createSourceNode(expression, chunks);
}

@@ -294,25 +405,34 @@ needsParentheses(expression) {

printParenthesizedExpression(expression) {
return `(${this.printExpression(expression.innerEpxression)})`;
return this.createSourceNode(expression, ["(", this.printExpression(expression.innerEpxression), ")"]);
}
printCallExpression(expression) {
const params = expression.params ? expression.params.map(e => this.printExpression(e)).join(", ") : "";
return this.needsParentheses(expression.expression)
? `(${this.printExpression(expression.expression)})(${params})`
: `${this.printExpression(expression.expression)}(${params})`;
const chunks = [];
const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e)));
if (this.needsParentheses(expression.expression)) {
chunks.push("(", this.printExpression(expression.expression), ")(", ...parameterChunks, ")");
}
else {
chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")");
}
return this.concatNodes(...chunks);
}
printMethodCallExpression(expression) {
const params = expression.params.map(e => this.printExpression(e)).join(", ");
const prefix = this.printExpression(expression.prefixExpression);
const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e)));
const name = this.printIdentifier(expression.name);
return `${prefix}:${name}(${params})`;
return this.concatNodes(prefix, ":", name, "(", ...parameterChunks, ")");
}
printIdentifier(expression) {
return expression.text;
return this.createSourceNode(expression, expression.text);
}
printTableIndexExpression(expression) {
const table = this.printExpression(expression.table);
const chunks = [];
chunks.push(this.printExpression(expression.table));
if (tstl.isStringLiteral(expression.index) && TSHelper_1.TSHelper.isValidLuaIdentifier(expression.index.value)) {
return `${table}.${expression.index.value}`;
chunks.push(".", this.createSourceNode(expression.index, expression.index.value));
}
return `${table}[${this.printExpression(expression.index)}]`;
else {
chunks.push("[", this.printExpression(expression.index), "]");
}
return this.createSourceNode(expression, chunks);
}

@@ -332,2 +452,12 @@ printOperator(kind) {

}
joinChunks(separator, chunks) {
const result = [];
for (let i = 0; i < chunks.length; i++) {
result.push(chunks[i]);
if (i < chunks.length - 1) {
result.push(separator);
}
}
return result;
}
}

@@ -334,0 +464,0 @@ /* tslint:disable:object-literal-sort-keys */

import * as ts from "typescript";
import * as tstl from "./LuaAST";
export interface TranspileResult {
lua: string;
luaAST: tstl.Node;
sourceMap: string;
}
export declare class LuaTranspiler {

@@ -14,5 +19,4 @@ private program;

emitSourceFile(sourceFile: ts.SourceFile): number;
transpileSourceFile(sourceFile: ts.SourceFile): string;
transpileSourceFileKeepAST(sourceFile: ts.SourceFile): [tstl.Block, string];
transpileSourceFile(sourceFile: ts.SourceFile): TranspileResult;
reportDiagnostic(diagnostic: ts.Diagnostic): void;
}

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

const rootDir = this.options.rootDir;
const lua = this.transpileSourceFile(sourceFile);
const { lua, luaAST, sourceMap } = this.transpileSourceFile(sourceFile);
let outPath = sourceFile.fileName;

@@ -90,2 +90,5 @@ if (this.options.outDir !== this.options.rootDir) {

ts.sys.writeFile(outPath, lua);
if (this.options.sourceMap) {
ts.sys.writeFile(outPath + ".map", sourceMap);
}
}

@@ -112,10 +115,5 @@ catch (exception) {

// Print AST
return this.luaPrinter.print(luaAST, lualibFeatureSet);
const [lua, sourceMap] = this.luaPrinter.print(luaAST, lualibFeatureSet, sourceFile.fileName);
return { lua, luaAST, sourceMap };
}
transpileSourceFileKeepAST(sourceFile) {
// Transform AST
const [luaAST, lualibFeatureSet] = this.luaTransformer.transformSourceFile(sourceFile);
// Print AST
return [luaAST, this.luaPrinter.print(luaAST, lualibFeatureSet)];
}
reportDiagnostic(diagnostic) {

@@ -122,0 +120,0 @@ if (diagnostic.file) {

import * as ts from "typescript";
export declare class TranspileError extends Error {
node: ts.Node;
name: string;
constructor(message: string, node: ts.Node);
}

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

this.node = node;
this.name = 'TranspileError';
}

@@ -9,0 +10,0 @@ }

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

static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type;
static collectCustomDecorators(symbol: ts.Symbol, checker: ts.TypeChecker, decMap: Map<DecoratorKind, Decorator>): void;
static collectCustomDecorators(source: ts.Symbol | ts.Signature, checker: ts.TypeChecker, decMap: Map<DecoratorKind, Decorator>): void;
static getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
static getCustomFileDirectives(file: ts.SourceFile): Map<DecoratorKind, Decorator>;
static getCustomSignatureDirectives(signature: ts.Signature, checker: ts.TypeChecker): Map<DecoratorKind, Decorator>;
static findFirstNodeAbove<T extends ts.Node>(node: ts.Node, callback: (n: ts.Node) => n is T): T;

@@ -34,0 +35,0 @@ static isBinaryAssignmentToken(token: ts.SyntaxKind): [boolean, ts.BinaryOperator];

@@ -29,2 +29,4 @@ "use strict";

"join",
"flat",
"flatMap",
]);

@@ -151,2 +153,16 @@ const defaultArrayPropertyNames = new Set([

if (ts.isCallExpression(node)) {
const signature = checker.getResolvedSignature(node);
if (signature) {
if (TSHelper.getCustomSignatureDirectives(signature, checker).has(Decorator_1.DecoratorKind.TupleReturn)) {
return true;
}
// Only check function type for directive if it is declared as an interface or type alias
const declaration = signature.getDeclaration();
const isInterfaceOrAlias = declaration && declaration.parent
&& ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration))
|| ts.isTypeAliasDeclaration(declaration.parent));
if (!isInterfaceOrAlias) {
return false;
}
}
const type = checker.getTypeAtLocation(node.expression);

@@ -169,2 +185,7 @@ return TSHelper.getCustomDecorators(type, checker).has(Decorator_1.DecoratorKind.TupleReturn);

}
// Check all overloads for directive
const signatures = functionType.getCallSignatures();
if (signatures && signatures.some(s => TSHelper.getCustomSignatureDirectives(s, checker).has(Decorator_1.DecoratorKind.TupleReturn))) {
return true;
}
const decorators = TSHelper.getCustomDecorators(functionType, checker);

@@ -185,4 +206,4 @@ return decorators.has(Decorator_1.DecoratorKind.TupleReturn);

}
static collectCustomDecorators(symbol, checker, decMap) {
const comments = symbol.getDocumentationComment(checker);
static collectCustomDecorators(source, checker, decMap) {
const comments = source.getDocumentationComment(checker);
const decorators = comments.filter(comment => comment.kind === "text")

@@ -205,3 +226,3 @@ .map(comment => comment.text.split("\n"))

});
symbol.getJsDocTags().forEach(tag => {
source.getJsDocTags().forEach(tag => {
if (Decorator_1.Decorator.isValid(tag.name)) {

@@ -237,2 +258,7 @@ const dec = new Decorator_1.Decorator(tag.name, tag.text ? tag.text.split(" ") : []);

}
static getCustomSignatureDirectives(signature, checker) {
const directivesMap = new Map();
TSHelper.collectCustomDecorators(signature, checker, directivesMap);
return directivesMap;
}
// Search up until finding a node satisfying the callback

@@ -239,0 +265,0 @@ static findFirstNodeAbove(node, callback) {

{
"name": "typescript-to-lua",
"version": "0.17.0",
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
"repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
"license": "MIT",
"version": "0.16.1",
"repository": "https://github.com/Perryvw/TypescriptToLua",
"keywords": [

@@ -22,16 +23,13 @@ "typescript",

"build-lualib": "ts-node ./build_lualib.ts",
"pretest": "npm run clean && npm run style-check && npm run build && tsc -p ./test/tsconfig.json",
"test": "node ./test/runner.js",
"posttest": "npm run clean",
"coverage": "nyc --source-map=true npm test && nyc report --reporter=text-lcov > coverage.lcov",
"coverage-html": "nyc --source-map=true npm test && nyc report --reporter=html",
"test-threaded": "npm run pretest && node ./test/threaded_runner.js && npm run posttest",
"test-fast": "npm run pretest && node ./test/runner.js --ignoreDiagnostics && npm run posttest",
"clean": "rimraf \"src/**/*.js\" \"src/**/*.js.map\" \"test/**/*.js\" \"test/**/*.js.map\" \"test/compiler/testfiles/*.lua\"",
"pretest": "ts-node --transpile-only ./build_lualib.ts",
"test": "jest",
"lint": "npm run lint:tslint && npm run lint:prettier",
"lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)",
"lint:tslint": "tslint -p . && tslint -p test && tslint src/lualib/*.ts",
"fix:prettier": "prettier --check --write **/*.{js,ts,yml,json}",
"release-major": "npm version major",
"release-minor": "npm version minor",
"release-patch": "npm version patch",
"release-minor": "npm version minor",
"release-major": "npm version major",
"preversion": "npm run build && npm test",
"postversion": "git push && git push --tags",
"style-check": "tslint -p . && tslint -c ./tslint.json src/lualib/*.ts"
"postversion": "git push && git push --tags"
},

@@ -41,14 +39,2 @@ "bin": {

},
"nyc": {
"all": true,
"extension": [
".ts"
],
"include": [
"src/**/*"
],
"exclude": [
"src/lualib/*"
]
},
"engines": {

@@ -58,2 +44,3 @@ "node": ">=8.5.0"

"dependencies": {
"source-map": "^0.7.3",
"typescript": "^3.3.1"

@@ -63,12 +50,11 @@ },

"@types/glob": "^5.0.35",
"@types/jest": "^24.0.11",
"@types/node": "^9.6.23",
"alsatian": "^2.3.0",
"codecov": "^3.2.0",
"deep-equal": "^1.0.1",
"fengari": "^0.1.2",
"flatted": "^2.0.0",
"glob": "^7.1.2",
"nyc": "^13.3.0",
"jest": "^24.5.0",
"jest-circus": "^24.5.0",
"prettier": "^1.16.4",
"rimraf": "^2.6.3",
"threads": "^0.12.0",
"ts-jest": "^24.0.0",
"ts-node": "^7.0.0",

@@ -75,0 +61,0 @@ "tslint": "^5.10.0"

@@ -41,11 +41,12 @@ <div align="center">

**Example tsconfig.json**
```
```json
{
"compilerOptions": {
"noImplicitAny" : true,
"noImplicitThis" : true,
"alwaysStrict" : true,
"strictNullChecks": true
"target": "esnext",
"lib": ["es2015", "es2016", "es2017", "es2018", "esnext"],
"strict": true
},
"luaTarget": "JIT"
"tstl": {
"luaTarget": "JIT"
}
}

@@ -52,0 +53,0 @@ ```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

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