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.39.6 to 0.40.0

dist/transpilation/resolve.d.ts

17

CHANGELOG.md
# Changelog
## 0.40.0
- Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs.
- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg) for instructions how to upgrade.
- Added support for `array.entries()`.
- Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info.
- Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua.
- Fixed an issue where using TypeScript transformer plugins would cause invalid namespace and module code, as well as breaking hoisting.
- Fixed invalid switch statement output when the `default` clause was not the last clause in the switch.
- Fixed missing LuaLib dependency when using `string.split`.
- Fixed **lots** of bundling bugs and issues, also added the TypeScriptToLua header to the top of the bundle unless _noHeader_ is specified.
Under the hood:
- Various improvements to testing infrastructure for testing (virtual) projects with multiple files.
## 0.39.0

@@ -4,0 +21,0 @@

@@ -9,2 +9,8 @@ "use strict";

{
name: "buildMode",
description: "'default' or 'library'. Compiling as library will not resolve external dependencies.",
type: "enum",
choices: Object.values(CompilerOptions_1.BuildMode),
},
{
name: "luaBundle",

@@ -11,0 +17,0 @@ description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.",

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

export declare type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> & {
buildMode?: BuildMode;
noImplicitSelf?: boolean;

@@ -48,4 +49,8 @@ noHeader?: boolean;

}
export declare enum BuildMode {
Default = "default",
Library = "library"
}
export declare const isBundleEnabled: (options: CompilerOptions) => boolean;
export declare function validateOptions(options: CompilerOptions): ts.Diagnostic[];
export {};

7

dist/CompilerOptions.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateOptions = exports.isBundleEnabled = exports.LuaTarget = exports.LuaLibImportKind = void 0;
exports.validateOptions = exports.isBundleEnabled = exports.BuildMode = exports.LuaTarget = exports.LuaLibImportKind = void 0;
const diagnosticFactories = require("./transpilation/diagnostics");

@@ -21,2 +21,7 @@ var LuaLibImportKind;

})(LuaTarget = exports.LuaTarget || (exports.LuaTarget = {}));
var BuildMode;
(function (BuildMode) {
BuildMode["Default"] = "default";
BuildMode["Library"] = "library";
})(BuildMode = exports.BuildMode || (exports.BuildMode = {}));
const isBundleEnabled = (options) => options.luaBundle !== undefined && options.luaBundleEntry !== undefined;

@@ -23,0 +28,0 @@ exports.isBundleEnabled = isBundleEnabled;

@@ -6,2 +6,3 @@ import { SourceNode } from "source-map";

export declare const escapeString: (value: string) => string;
export declare const tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
declare type SourceChunk = string | SourceNode;

@@ -8,0 +9,0 @@ export declare type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, file: lua.File) => PrintResult;

24

dist/LuaPrinter.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LuaPrinter = exports.createPrinter = exports.escapeString = void 0;
const path = require("path");
exports.LuaPrinter = exports.createPrinter = exports.tstlHeader = exports.escapeString = void 0;
const source_map_1 = require("source-map");

@@ -27,2 +26,3 @@ const CompilerOptions_1 = require("./CompilerOptions");

exports.escapeString = escapeString;
exports.tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
/**

@@ -79,19 +79,3 @@ * Checks that a name is valid for use in lua function declaration syntax:

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);
}
else {
this.sourceFile = path.basename(fileName); // File will be in same dir as source
}
this.sourceFile = fileName;
}

@@ -146,3 +130,3 @@ print(file) {

if (!this.options.noHeader) {
header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
header += exports.tstlHeader;
}

@@ -149,0 +133,0 @@ const luaLibImport = (_a = this.options.luaLibImport) !== null && _a !== void 0 ? _a : CompilerOptions_1.LuaLibImportKind.Require;

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

};
export declare const invalidForRangeCall: ((node: ts.Node, message: string) => ts.Diagnostic) & {
code: number;
};
export declare const invalidRangeUse: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {

@@ -38,20 +35,2 @@ code: number;

};
export declare const luaTableMustBeAmbient: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
code: number;
};
export declare const luaTableCannotBeExtended: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
code: number;
};
export declare const luaTableInvalidInstanceOf: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
code: number;
};
export declare const luaTableCannotBeAccessedDynamically: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
code: number;
};
export declare const luaTableForbiddenUsage: ((node: ts.Node, description: string) => ts.Diagnostic) & {
code: number;
};
export declare const luaIteratorForbiddenUsage: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
code: number;
};
export declare const invalidMultiIterableWithoutDestructuring: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {

@@ -75,5 +54,2 @@ code: number;

};
export declare const unresolvableRequirePath: ((node: ts.Node, path: string) => ts.Diagnostic) & {
code: number;
};
export declare const unsupportedVarDeclaration: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {

@@ -80,0 +56,0 @@ code: number;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.optionalChainingNotSupported = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidTableSetExpression = exports.invalidTableDeleteExpression = exports.invalidTableExtensionUse = exports.invalidOperatorMappingUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.unresolvableRequirePath = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidMultiIterableWithoutDestructuring = exports.luaIteratorForbiddenUsage = exports.luaTableForbiddenUsage = exports.luaTableCannotBeAccessedDynamically = exports.luaTableInvalidInstanceOf = exports.luaTableCannotBeExtended = exports.luaTableMustBeAmbient = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.invalidForRangeCall = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
exports.optionalChainingNotSupported = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidTableSetExpression = exports.invalidTableDeleteExpression = exports.invalidTableExtensionUse = exports.invalidOperatorMappingUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidMultiIterableWithoutDestructuring = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
const ts = require("typescript");

@@ -35,14 +35,5 @@ const CompilerOptions_1 = require("../../CompilerOptions");

exports.annotationInvalidArgumentCount = createErrorDiagnosticFactory((kind, got, expected) => `'@${kind}' expects ${expected} arguments, but got ${got}.`);
exports.invalidForRangeCall = createErrorDiagnosticFactory((message) => `Invalid @forRange call: ${message}.`);
exports.invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop.");
exports.invalidVarargUse = createErrorDiagnosticFactory("$vararg can only be used in a spread element ('...$vararg') in global scope.");
exports.invalidRangeControlVariable = createErrorDiagnosticFactory("For loop using $range must declare a single control variable.");
exports.luaTableMustBeAmbient = createErrorDiagnosticFactory("Classes with the '@luaTable' annotation must be ambient.");
exports.luaTableCannotBeExtended = createErrorDiagnosticFactory("Cannot extend classes with the '@luaTable' annotation.");
exports.luaTableInvalidInstanceOf = createErrorDiagnosticFactory("The instanceof operator cannot be used with a '@luaTable' class.");
exports.luaTableCannotBeAccessedDynamically = createErrorDiagnosticFactory("@luaTable cannot be accessed dynamically.");
exports.luaTableForbiddenUsage = createErrorDiagnosticFactory((description) => `Invalid @luaTable usage: ${description}.`);
exports.luaIteratorForbiddenUsage = createErrorDiagnosticFactory("Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " +
"You must use a destructuring statement to catch results from a lua iterator with " +
"the '@tupleReturn' annotation.");
exports.invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory("LuaIterable with a LuaMultiReturn return value type must be destructured.");

@@ -55,3 +46,2 @@ exports.unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory("Accessors in object literal are not supported.");

exports.invalidAmbientIdentifierName = createErrorDiagnosticFactory((text) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.`);
exports.unresolvableRequirePath = createErrorDiagnosticFactory((path) => `Cannot create require path. Module '${path}' does not exist within --rootDir.`);
exports.unsupportedVarDeclaration = createErrorDiagnosticFactory("`var` declarations are not supported. Use `let` or `const` instead.");

@@ -58,0 +48,0 @@ exports.invalidMultiFunctionUse = createErrorDiagnosticFactory("The $multi function must be called in a return statement.");

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

const multi_1 = require("./language-extensions/multi");
const lua_table_1 = require("./lua-table");
function transformElementAccessArgument(context, node) {

@@ -27,3 +26,2 @@ const index = context.transformExpression(node.argumentExpression);

const transformElementAccessExpression = (node, context) => {
lua_table_1.validateLuaTableElementAccessExpression(context, node);
const constEnumValue = enum_1.tryGetConstEnumValue(context, node);

@@ -53,36 +51,35 @@ if (constEnumValue) {

exports.transformElementAccessExpression = transformElementAccessExpression;
const transformPropertyAccessExpression = (expression, context) => {
if (ts.isOptionalChain(expression)) {
context.diagnostics.push(diagnostics_1.optionalChainingNotSupported(expression));
const transformPropertyAccessExpression = (node, context) => {
const property = node.name.text;
const type = context.checker.getTypeAtLocation(node.expression);
const annotations = annotations_1.getTypeAnnotations(type);
if (annotations.has(annotations_1.AnnotationKind.LuaTable)) {
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.LuaTable));
}
const constEnumValue = enum_1.tryGetConstEnumValue(context, expression);
if (ts.isOptionalChain(node)) {
context.diagnostics.push(diagnostics_1.optionalChainingNotSupported(node));
}
const constEnumValue = enum_1.tryGetConstEnumValue(context, node);
if (constEnumValue) {
return constEnumValue;
}
const luaTableResult = lua_table_1.transformLuaTablePropertyAccessExpression(context, expression);
if (luaTableResult) {
return luaTableResult;
}
const builtinResult = builtins_1.transformBuiltinPropertyAccessExpression(context, expression);
const builtinResult = builtins_1.transformBuiltinPropertyAccessExpression(context, node);
if (builtinResult) {
return builtinResult;
}
if (ts.isCallExpression(expression.expression) && multi_1.returnsMultiType(context, expression.expression)) {
context.diagnostics.push(diagnostics_1.invalidMultiReturnAccess(expression));
if (ts.isCallExpression(node.expression) && multi_1.returnsMultiType(context, node.expression)) {
context.diagnostics.push(diagnostics_1.invalidMultiReturnAccess(node));
}
const property = expression.name.text;
const type = context.checker.getTypeAtLocation(expression.expression);
const annotations = annotations_1.getTypeAnnotations(type);
// Do not output path for member only enums
if (annotations.has(annotations_1.AnnotationKind.CompileMembersOnly)) {
if (ts.isPropertyAccessExpression(expression.expression)) {
if (ts.isPropertyAccessExpression(node.expression)) {
// in case of ...x.enum.y transform to ...x.y
return lua.createTableIndexExpression(context.transformExpression(expression.expression.expression), lua.createStringLiteral(property), expression);
return lua.createTableIndexExpression(context.transformExpression(node.expression.expression), lua.createStringLiteral(property), node);
}
else {
return lua.createIdentifier(property, expression);
return lua.createIdentifier(property, node);
}
}
const callPath = context.transformExpression(expression.expression);
return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), expression);
const callPath = context.transformExpression(node.expression);
return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), node);
};

@@ -89,0 +86,0 @@ exports.transformPropertyAccessExpression = transformPropertyAccessExpression;

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

const access_1 = require("../access");
const lua_table_1 = require("../lua-table");
const destructuring_assignments_1 = require("./destructuring-assignments");

@@ -21,7 +20,4 @@ const multi_1 = require("../language-extensions/multi");

function transformAssignmentLeftHandSideExpression(context, node) {
var _a;
const symbol = context.checker.getSymbolAtLocation(node);
const left = ts.isPropertyAccessExpression(node)
? (_a = lua_table_1.transformLuaTablePropertyAccessInAssignment(context, node)) !== null && _a !== void 0 ? _a : context.transformExpression(node)
: context.transformExpression(node);
const left = context.transformExpression(node);
return lua.isIdentifier(left) && symbol && export_1.isSymbolExported(context, symbol)

@@ -99,4 +95,2 @@ ? export_1.createExportedIdentifier(context, left)

if (ts.isPropertyAccessExpression(expression.left)) {
// Called only for validation
lua_table_1.transformLuaTablePropertyAccessInAssignment(context, expression.left);
// Property access

@@ -103,0 +97,0 @@ indexExpression = lua.createStringLiteral(expression.left.name.text);

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

const lua = require("../../../LuaAST");
const annotations_1 = require("../../utils/annotations");
const diagnostics_1 = require("../../utils/diagnostics");
const lua_ast_1 = require("../../utils/lua-ast");

@@ -81,6 +79,2 @@ const lualib_1 = require("../../utils/lualib");

const rhsType = context.checker.getTypeAtLocation(node.right);
const annotations = annotations_1.getTypeAnnotations(rhsType);
if (annotations.has(annotations_1.AnnotationKind.LuaTable)) {
context.diagnostics.push(diagnostics_1.luaTableInvalidInstanceOf(node));
}
if (typescript_1.isStandardLibraryType(context, rhsType, "ObjectConstructor")) {

@@ -87,0 +81,0 @@ return lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.InstanceOfObject, node, lhs);

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

const access_1 = require("./access");
const lua_table_1 = require("./lua-table");
const multi_1 = require("./language-extensions/multi");

@@ -168,6 +167,2 @@ const operators_1 = require("./language-extensions/operators");

const transformCallExpression = (node, context) => {
const luaTableResult = lua_table_1.transformLuaTableCallExpression(context, node);
if (luaTableResult) {
return luaTableResult;
}
const isTupleReturn = annotations_1.isTupleReturnCall(context, node);

@@ -201,2 +196,7 @@ const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) && annotations_1.isInTupleReturnFunction(context, node);

if (ts.isPropertyAccessExpression(node.expression)) {
const ownerType = context.checker.getTypeAtLocation(node.expression.expression);
const annotations = annotations_1.getTypeAnnotations(ownerType);
if (annotations.has(annotations_1.AnnotationKind.LuaTable)) {
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.LuaTable));
}
const result = transformPropertyCall(context, node);

@@ -203,0 +203,0 @@ return wrapResult ? lua_ast_1.wrapInTable(result) : result;

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

const transform_1 = require("../../utils/transform");
const typescript_1 = require("../../utils/typescript");
const identifier_1 = require("../identifier");

@@ -72,12 +71,2 @@ const decorators_1 = require("./decorators");

}
// You cannot extend LuaTable classes
if (extendedType) {
const annotations = annotations_1.getTypeAnnotations(extendedType);
if (annotations.has(annotations_1.AnnotationKind.LuaTable)) {
context.diagnostics.push(diagnostics_1.luaTableCannotBeExtended(extendedTypeNode));
}
}
if (annotations.has(annotations_1.AnnotationKind.LuaTable) && !typescript_1.isAmbientNode(classDeclaration)) {
context.diagnostics.push(diagnostics_1.luaTableMustBeAmbient(classDeclaration));
}
// Get all properties with value

@@ -84,0 +73,0 @@ const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer);

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

const table_1 = require("../language-extensions/table");
const lua_table_1 = require("../lua-table");
const builtinErrorTypeNames = new Set([

@@ -52,5 +51,6 @@ "Error",

var _a;
const luaTableResult = lua_table_1.transformLuaTableNewExpression(context, node);
if (luaTableResult) {
return luaTableResult;
const type = context.checker.getTypeAtLocation(node);
const annotations = annotations_1.getTypeAnnotations(type);
if (annotations.has(annotations_1.AnnotationKind.LuaTable)) {
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.LuaTable));
}

@@ -65,5 +65,3 @@ if (table_1.isTableNewCall(context, node)) {

: [lua.createBooleanLiteral(true)];
const type = context.checker.getTypeAtLocation(node);
checkForLuaLibType(context, type);
const annotations = annotations_1.getTypeAnnotations(type);
const customConstructorAnnotation = annotations.get(annotations_1.AnnotationKind.CustomConstructor);

@@ -70,0 +68,0 @@ if (customConstructorAnnotation) {

@@ -8,15 +8,11 @@ "use strict";

const table_1 = require("./language-extensions/table");
const lua_table_1 = require("./lua-table");
const unary_expression_1 = require("./unary-expression");
const transformExpressionStatement = (node, context) => {
const luaTableResult = lua_table_1.transformLuaTableExpressionStatement(context, node);
if (luaTableResult) {
return luaTableResult;
const expression = node.expression;
if (ts.isCallExpression(expression) && table_1.isTableDeleteCall(context, expression)) {
return table_1.transformTableDeleteExpression(context, expression);
}
if (ts.isCallExpression(node.expression) && table_1.isTableDeleteCall(context, node.expression)) {
return table_1.transformTableDeleteExpression(context, node.expression);
if (ts.isCallExpression(expression) && table_1.isTableSetCall(context, expression)) {
return table_1.transformTableSetExpression(context, expression);
}
if (ts.isCallExpression(node.expression) && table_1.isTableSetCall(context, node.expression)) {
return table_1.transformTableSetExpression(context, node.expression);
}
const unaryExpressionResult = unary_expression_1.transformUnaryExpressionStatement(context, node);

@@ -30,3 +26,2 @@ if (unaryExpressionResult) {

}
const expression = ts.isExpressionStatement(node) ? node.expression : node;
const result = context.transformExpression(expression);

@@ -33,0 +28,0 @@ return lua.isCallExpression(result) || lua.isMethodCallExpression(result)

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

const symbols_1 = require("../utils/symbols");
const typescript_1 = require("../utils/typescript");
const multi_1 = require("./language-extensions/multi");

@@ -39,6 +38,3 @@ const operators_1 = require("./language-extensions/operators");

if (annotations_1.isForRangeType(context, identifier)) {
const callExpression = typescript_1.findFirstNodeAbove(identifier, ts.isCallExpression);
if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(identifier, "can be used only as an iterable in a for...of loop"));
}
context.diagnostics.push(diagnostics_1.annotationRemoved(identifier, annotations_1.AnnotationKind.ForRange));
}

@@ -45,0 +41,0 @@ const text = safe_names_1.hasUnsafeIdentifierName(context, identifier) ? safe_names_1.createSafeName(identifier.text) : identifier.text;

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

const lua = require("../../../LuaAST");
const utils_1 = require("../../../utils");
const annotations_1 = require("../../utils/annotations");

@@ -12,80 +11,7 @@ const diagnostics_1 = require("../../utils/diagnostics");

const typescript_1 = require("../../utils/typescript");
const call_1 = require("../call");
const identifier_1 = require("../identifier");
const iterable_1 = require("../language-extensions/iterable");
const range_1 = require("../language-extensions/range");
const variable_declaration_1 = require("../variable-declaration");
const utils_2 = require("./utils");
function transformForRangeStatement(context, statement, block) {
var _a;
utils_1.assert(ts.isCallExpression(statement.expression));
context.diagnostics.push(diagnostics_1.annotationDeprecated(statement.expression, annotations_1.AnnotationKind.ForRange));
const callArguments = statement.expression.arguments;
if (callArguments.length !== 2 && callArguments.length !== 3) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(statement.expression, `Expected 2-3 arguments, but got ${callArguments.length}`));
}
if (statement.expression.arguments.some(a => !typescript_1.isNumberType(context, context.checker.getTypeAtLocation(a)))) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(statement.expression, "arguments must be numbers"));
}
const controlVariable = (_a = getControlVariable()) !== null && _a !== void 0 ? _a : lua.createAnonymousIdentifier();
function getControlVariable() {
if (!ts.isVariableDeclarationList(statement.initializer)) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(statement.initializer, "loop must declare it's own control variable"));
return;
}
const binding = utils_2.getVariableDeclarationBinding(context, statement.initializer);
if (!ts.isIdentifier(binding)) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(statement.initializer, "destructuring cannot be used"));
return;
}
if (!typescript_1.isNumberType(context, context.checker.getTypeAtLocation(binding))) {
context.diagnostics.push(diagnostics_1.invalidForRangeCall(statement.expression, "function must return Iterable<number>"));
}
return identifier_1.transformIdentifier(context, binding);
}
const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = call_1.transformArguments(context, callArguments, context.checker.getResolvedSignature(statement.expression));
return lua.createForStatement(block, controlVariable, start, limit, step, statement);
}
function transformForOfLuaIteratorStatement(context, statement, block) {
const luaIterator = context.transformExpression(statement.expression);
const type = context.checker.getTypeAtLocation(statement.expression);
const tupleReturn = annotations_1.getTypeAnnotations(type).has(annotations_1.AnnotationKind.TupleReturn);
let identifiers = [];
if (tupleReturn) {
// LuaIterator + TupleReturn
if (ts.isVariableDeclarationList(statement.initializer)) {
// Variables declared in for loop
// for ${initializer} in ${iterable} do
const binding = utils_2.getVariableDeclarationBinding(context, statement.initializer);
if (ts.isArrayBindingPattern(binding)) {
identifiers = binding.elements.map(e => variable_declaration_1.transformArrayBindingElement(context, e));
}
else {
context.diagnostics.push(diagnostics_1.luaIteratorForbiddenUsage(binding));
}
}
else if (ts.isArrayLiteralExpression(statement.initializer)) {
// Variables NOT declared in for loop - catch iterator values in temps and assign
// for ____value0 in ${iterable} do
// ${initializer} = ____value0
identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`));
if (identifiers.length > 0) {
block.statements.unshift(lua.createAssignmentStatement(statement.initializer.elements.map(e => utils_1.cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression)), identifiers));
}
}
else {
context.diagnostics.push(diagnostics_1.luaIteratorForbiddenUsage(statement.initializer));
}
}
else {
// LuaIterator (no TupleReturn)
identifiers.push(utils_2.transformForInitializer(context, statement.initializer, block));
}
if (identifiers.length === 0) {
identifiers.push(lua.createAnonymousIdentifier());
}
return lua.createForInStatement(block, identifiers, [luaIterator], statement);
}
const utils_1 = require("./utils");
function transformForOfArrayStatement(context, statement, block) {
const valueVariable = utils_2.transformForInitializer(context, statement.initializer, block);
const valueVariable = utils_1.transformForInitializer(context, statement.initializer, block);
const ipairsCall = lua.createCallExpression(lua.createIdentifier("ipairs"), [

@@ -97,3 +23,3 @@ context.transformExpression(statement.expression),

function transformForOfIteratorStatement(context, statement, block) {
const valueVariable = utils_2.transformForInitializer(context, statement.initializer, block);
const valueVariable = utils_1.transformForInitializer(context, statement.initializer, block);
const iterable = lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.Iterator, statement.expression, context.transformExpression(statement.expression));

@@ -103,3 +29,3 @@ return lua.createForInStatement(block, [lua.createAnonymousIdentifier(), valueVariable], [iterable], statement);

const transformForOfStatement = (node, context) => {
const body = lua.createBlock(utils_2.transformLoopBody(context, node));
const body = lua.createBlock(utils_1.transformLoopBody(context, node));
if (ts.isCallExpression(node.expression) && range_1.isRangeFunction(context, node.expression)) {

@@ -109,3 +35,3 @@ return range_1.transformRangeStatement(context, node, body);

else if (ts.isCallExpression(node.expression) && annotations_1.isForRangeType(context, node.expression.expression)) {
return transformForRangeStatement(context, node, body);
context.diagnostics.push(diagnostics_1.annotationRemoved(node.expression, annotations_1.AnnotationKind.ForRange));
}

@@ -116,3 +42,3 @@ else if (iterable_1.isIterableExpression(context, node.expression)) {

else if (annotations_1.isLuaIteratorType(context, node.expression)) {
return transformForOfLuaIteratorStatement(context, node, body);
context.diagnostics.push(diagnostics_1.annotationRemoved(node.expression, annotations_1.AnnotationKind.LuaIterator));
}

@@ -119,0 +45,0 @@ else if (typescript_1.isArrayType(context, context.checker.getTypeAtLocation(node.expression))) {

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

const lua = require("../../../LuaAST");
const utils_1 = require("../../../utils");
const annotations_1 = require("../../utils/annotations");

@@ -16,26 +15,8 @@ const export_1 = require("../../utils/export");

const literal_1 = require("../literal");
const diagnostics_1 = require("../../utils/diagnostics");
const getAbsoluteImportPath = (relativePath, directoryPath, options) => !relativePath.startsWith(".") && options.baseUrl
? path.resolve(options.baseUrl, relativePath)
: path.resolve(directoryPath, relativePath);
function getImportPath(context, relativePath, node) {
const { options, sourceFile } = context;
const { fileName } = sourceFile;
const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve(".");
const absoluteImportPath = path.format(path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)));
const absoluteRootDirPath = path.format(path.parse(rootDir));
if (absoluteImportPath.includes(absoluteRootDirPath)) {
return utils_1.formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1));
}
else {
context.diagnostics.push(diagnostics_1.unresolvableRequirePath(node, relativePath));
return relativePath;
}
}
function shouldResolveModulePath(context, moduleSpecifier) {
function isNoResolutionPath(context, moduleSpecifier) {
const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier);
if (!moduleOwnerSymbol)
return true;
return false;
const annotations = annotations_1.getSymbolAnnotations(moduleOwnerSymbol);
return !annotations.has(annotations_1.AnnotationKind.NoResolution);
return annotations.has(annotations_1.AnnotationKind.NoResolution);
}

@@ -45,4 +26,4 @@ function createModuleRequire(context, moduleSpecifier, tsOriginal = moduleSpecifier) {

if (ts.isStringLiteral(moduleSpecifier)) {
const modulePath = shouldResolveModulePath(context, moduleSpecifier)
? getImportPath(context, moduleSpecifier.text.replace(/"/g, ""), moduleSpecifier)
const modulePath = isNoResolutionPath(context, moduleSpecifier)
? `@NoResolution:${moduleSpecifier.text}`
: moduleSpecifier.text;

@@ -49,0 +30,0 @@ params.push(lua.createStringLiteral(modulePath));

@@ -51,4 +51,3 @@ "use strict";

if (annotations_1.isVarargType(context, node.expression)) {
context.diagnostics.push(diagnostics_1.annotationDeprecated(node, annotations_1.AnnotationKind.Vararg));
return lua.createDotsLiteral(node);
context.diagnostics.push(diagnostics_1.annotationRemoved(node, annotations_1.AnnotationKind.Vararg));
}

@@ -55,0 +54,0 @@ const symbol = context.checker.getSymbolAtLocation(node.expression);

import * as ts from "typescript";
import { EmitFile, EmitHost, ProcessedFile } from "./utils";
export declare function getBundleResult(program: ts.Program, emitHost: EmitHost, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile];
import { EmitFile, ProcessedFile } from "./utils";
export declare function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile];

@@ -9,3 +9,4 @@ "use strict";

const diagnostics_1 = require("./diagnostics");
const createModulePath = (baseDir, pathToResolve) => LuaPrinter_1.escapeString(utils_1.formatPathToLuaPath(utils_1.trimExtension(path.relative(baseDir, pathToResolve))));
const transpiler_1 = require("./transpiler");
const createModulePath = (pathToResolve, program) => LuaPrinter_1.escapeString(utils_1.formatPathToLuaPath(utils_1.trimExtension(transpiler_1.getEmitPathRelativeToOutDir(pathToResolve, program))));
// Override `require` to read from ____modules table.

@@ -32,4 +33,3 @@ const requireOverride = `

`;
function getBundleResult(program, emitHost, files) {
var _a;
function getBundleResult(program, files) {
const diagnostics = [];

@@ -39,21 +39,19 @@ const options = program.getCompilerOptions();

const entryModule = utils_1.cast(options.luaBundleEntry, utils_1.isNonNull);
const rootDir = program.getCommonSourceDirectory();
const outDir = (_a = options.outDir) !== null && _a !== void 0 ? _a : rootDir;
const projectRootDir = options.configFilePath
? path.dirname(options.configFilePath)
: emitHost.getCurrentDirectory();
// Resolve project settings relative to project file.
const resolvedEntryModule = path.resolve(projectRootDir, entryModule);
const outputPath = utils_1.normalizeSlashes(path.resolve(projectRootDir, bundleFile));
if (!files.some(f => f.fileName === resolvedEntryModule)) {
const resolvedEntryModule = path.resolve(transpiler_1.getSourceDir(program), entryModule);
const outputPath = utils_1.normalizeSlashes(path.resolve(transpiler_1.getEmitOutDir(program), bundleFile));
if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) {
diagnostics.push(diagnostics_1.couldNotFindBundleEntryPoint(entryModule));
return [diagnostics, { outputPath, code: "" }];
}
// For each file: ["<module path>"] = function() <lua content> end,
const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(outDir, f.fileName)));
const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program)));
// Create ____modules table containing all entries from moduleTableEntries
const moduleTable = createModuleTableNode(moduleTableEntries);
// return require("<entry module path>")
const entryPoint = `return require(${createModulePath(outDir, resolvedEntryModule)})\n`;
const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]);
const entryPoint = `return require(${createModulePath(entryModule, program)})\n`;
const sourceChunks = [requireOverride, moduleTable, entryPoint];
if (!options.noHeader) {
sourceChunks.unshift(LuaPrinter_1.tstlHeader);
}
const bundleNode = joinSourceChunks(sourceChunks);
const { code, map } = bundleNode.toStringWithSourceMap();

@@ -73,3 +71,3 @@ return [

const tableEntryHead = `[${modulePath}] = function() `;
const tableEntryTail = "end,\n";
const tableEntryTail = " end,\n";
return joinSourceChunks([tableEntryHead, sourceMapNode !== null && sourceMapNode !== void 0 ? sourceMapNode : code, tableEntryTail]);

@@ -76,0 +74,0 @@ }

import * as ts from "typescript";
export declare const couldNotResolveRequire: ((requirePath: string, containingFile: string) => ts.Diagnostic) & {
code: number;
};
export declare const couldNotReadDependency: ((dependency: string) => ts.Diagnostic) & {
code: number;
};
export declare const toLoadItShouldBeTranspiled: ((kind: string, transform: string) => ts.Diagnostic) & {

@@ -3,0 +9,0 @@ code: number;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.usingLuaBundleWithInlineMightGenerateDuplicateCode = exports.luaBundleEntryIsRequired = exports.couldNotFindBundleEntryPoint = exports.transformerShouldBeATsTransformerFactory = exports.shouldHaveAExport = exports.couldNotResolveFrom = exports.toLoadItShouldBeTranspiled = void 0;
exports.usingLuaBundleWithInlineMightGenerateDuplicateCode = exports.luaBundleEntryIsRequired = exports.couldNotFindBundleEntryPoint = exports.transformerShouldBeATsTransformerFactory = exports.shouldHaveAExport = exports.couldNotResolveFrom = exports.toLoadItShouldBeTranspiled = exports.couldNotReadDependency = exports.couldNotResolveRequire = void 0;
const ts = require("typescript");
const utils_1 = require("../utils");
const createDiagnosticFactory = (getMessage) => utils_1.createSerialDiagnosticFactory((...args) => ({ messageText: getMessage(...args) }));
const createDiagnosticFactory = (getMessage, category = ts.DiagnosticCategory.Error) => utils_1.createSerialDiagnosticFactory((...args) => ({ messageText: getMessage(...args), category }));
exports.couldNotResolveRequire = createDiagnosticFactory((requirePath, containingFile) => `Could not resolve require path '${requirePath}' in file ${containingFile}.`);
exports.couldNotReadDependency = createDiagnosticFactory((dependency) => `Could not read content of resolved dependency ${dependency}.`);
exports.toLoadItShouldBeTranspiled = createDiagnosticFactory((kind, transform) => `To load "${transform}" ${kind} it should be transpiled or "ts-node" should be installed.`);

@@ -8,0 +10,0 @@ exports.couldNotResolveFrom = createDiagnosticFactory((kind, transform, base) => `Could not resolve "${transform}" ${kind} from "${base}".`);

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

const compilerHost = {
fileExists: () => true,
fileExists: fileName => fileName in input || ts.sys.fileExists(fileName),
getCanonicalFileName: fileName => fileName,

@@ -47,0 +47,0 @@ getCurrentDirectory: () => "",

import * as ts from "typescript";
export interface TranspiledFile {
outPath: string;
sourceFiles: ts.SourceFile[];

@@ -4,0 +5,0 @@ lua?: string;

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

if (!file) {
file = { sourceFiles: [...sourceFiles] };
file = { outPath: fileName, sourceFiles: [...sourceFiles] };
files.push(file);

@@ -13,0 +13,0 @@ }

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

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: file, ...printResult });
transpiledFiles.push({
sourceFiles: [sourceFile],
fileName: path.normalize(sourceFile.fileName),
luaAst: file,
...printResult,
});
}

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

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

}
export declare function getEmitPath(file: string, program: ts.Program): string;
export declare function getEmitPathRelativeToOutDir(fileName: string, program: ts.Program): string;
export declare function getSourceDir(program: ts.Program): string;
export declare function getEmitOutDir(program: ts.Program): string;
export declare function getProjectRoot(program: ts.Program): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transpiler = void 0;
exports.getProjectRoot = exports.getEmitOutDir = exports.getSourceDir = exports.getEmitPathRelativeToOutDir = exports.getEmitPath = exports.Transpiler = void 0;
const path = require("path");

@@ -10,2 +10,3 @@ const ts = require("typescript");

const bundle_1 = require("./bundle");
const resolve_1 = require("./resolve");
const transpile_1 = require("./transpile");

@@ -32,14 +33,15 @@ class Transpiler {

getEmitPlan(program, diagnostics, files) {
var _a;
const options = program.getCompilerOptions();
const rootDir = program.getCommonSourceDirectory();
const outDir = (_a = options.outDir) !== null && _a !== void 0 ? _a : rootDir;
const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")'));
if (lualibRequired) {
const fileName = utils_1.normalizeSlashes(path.resolve(rootDir, "lualib_bundle.lua"));
// Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan
const fileName = utils_1.normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua"));
files.unshift({ fileName, code: LuaLib_1.getLuaLibBundle(this.emitHost) });
}
// Resolve imported modules and modify output Lua requires
const resolutionResult = resolve_1.resolveDependencies(program, files, this.emitHost);
diagnostics.push(...resolutionResult.diagnostics);
let emitPlan;
if (CompilerOptions_1.isBundleEnabled(options)) {
const [bundleDiagnostics, bundleFile] = bundle_1.getBundleResult(program, this.emitHost, files);
const [bundleDiagnostics, bundleFile] = bundle_1.getBundleResult(program, resolutionResult.resolvedFiles);
diagnostics.push(...bundleDiagnostics);

@@ -49,7 +51,6 @@ emitPlan = [bundleFile];

else {
emitPlan = files.map(file => {
const pathInOutDir = path.resolve(outDir, path.relative(rootDir, file.fileName));
const outputPath = utils_1.normalizeSlashes(utils_1.trimExtension(pathInOutDir) + ".lua");
return { ...file, outputPath };
});
emitPlan = resolutionResult.resolvedFiles.map(file => ({
...file,
outputPath: getEmitPath(file.fileName, program),
}));
}

@@ -60,2 +61,46 @@ return { emitPlan };

exports.Transpiler = Transpiler;
function getEmitPath(file, program) {
const relativeOutputPath = getEmitPathRelativeToOutDir(file, program);
const outDir = getEmitOutDir(program);
return path.join(outDir, relativeOutputPath);
}
exports.getEmitPath = getEmitPath;
function getEmitPathRelativeToOutDir(fileName, program) {
const sourceDir = getSourceDir(program);
// Default output path is relative path in source dir
let emitPathSplits = path.relative(sourceDir, fileName).split(path.sep);
// If source is in a parent directory of source dir, move it into the source dir
emitPathSplits = emitPathSplits.filter(s => s !== "..");
// To avoid overwriting lua sources in node_modules, emit into lua_modules
if (emitPathSplits[0] === "node_modules") {
emitPathSplits[0] = "lua_modules";
}
// Make extension lua
emitPathSplits[emitPathSplits.length - 1] = utils_1.trimExtension(emitPathSplits[emitPathSplits.length - 1]) + ".lua";
return path.join(...emitPathSplits);
}
exports.getEmitPathRelativeToOutDir = getEmitPathRelativeToOutDir;
function getSourceDir(program) {
const rootDir = program.getCompilerOptions().rootDir;
if (rootDir && rootDir.length > 0) {
return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir);
}
return program.getCommonSourceDirectory();
}
exports.getSourceDir = getSourceDir;
function getEmitOutDir(program) {
const outDir = program.getCompilerOptions().outDir;
if (outDir && outDir.length > 0) {
return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir);
}
return program.getCommonSourceDirectory();
}
exports.getEmitOutDir = getEmitOutDir;
function getProjectRoot(program) {
// Try to get the directory the tsconfig is in
const tsConfigPath = program.getCompilerOptions().configFilePath;
// If no tsconfig is known, use common source directory
return tsConfigPath ? path.dirname(tsConfigPath) : program.getCommonSourceDirectory();
}
exports.getProjectRoot = getProjectRoot;
//# sourceMappingURL=transpiler.js.map
import * as ts from "typescript";
import * as lua from "../LuaAST";
export interface EmitHost {
fileExists(path: string): boolean;
getCurrentDirectory(): string;

@@ -5,0 +6,0 @@ readFile(path: string): string | undefined;

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

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

"dependencies": {
"enhanced-resolve": "^5.8.2",
"resolve": "^1.15.1",

@@ -47,0 +48,0 @@ "source-map": "^0.7.3",

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