typescript-to-lua 1.8.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -83,6 +83,9 @@ export declare const annotationRemoved: ((node: ts.Node, kind: AnnotationKind) =
83
83
  export declare const annotationDeprecated: ((node: ts.Node, kind: AnnotationKind) => ts.Diagnostic) & {
84
84
  code: number;
85
85
  };
86
+ export declare const truthyOnlyConditionalValue: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
87
+ code: number;
88
+ };
86
89
  export declare const notAllowedOptionalAssignment: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
87
90
  code: number;
88
91
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.undefinedInArrayLiteral = exports.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidCallExtensionUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTargetButOverrideAvailable = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidPairsIterableWithoutDestructuring = exports.invalidMultiIterableWithoutDestructuring = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
3
+ exports.undefinedInArrayLiteral = exports.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.truthyOnlyConditionalValue = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidCallExtensionUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTargetButOverrideAvailable = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidPairsIterableWithoutDestructuring = exports.invalidMultiIterableWithoutDestructuring = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
4
4
  const ts = require("typescript");
5
5
  const CompilerOptions_1 = require("../../CompilerOptions");
6
6
  const utils_1 = require("../../utils");
@@ -57,6 +57,7 @@ exports.annotationRemoved = createErrorDiagnosticFactory((kind) => `'@${kind}' h
57
57
  `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.`);
58
58
  exports.annotationDeprecated = createWarningDiagnosticFactory((kind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` +
59
59
  `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.`);
60
+ exports.truthyOnlyConditionalValue = createWarningDiagnosticFactory("Numbers and strings will always evaluate to true in Lua. Explicitly check the value with ===.");
60
61
  exports.notAllowedOptionalAssignment = createErrorDiagnosticFactory("The left-hand side of an assignment expression may not be an optional property access.");
61
62
  exports.awaitMustBeInAsyncFunction = createErrorDiagnosticFactory("Await can only be used inside async functions.");
62
63
  exports.unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory("Optional calls are not supported for builtin or language extension functions.");
@@ -6,11 +6,13 @@ const lua = require("../../LuaAST");
6
6
  const builtins_1 = require("../builtins");
7
7
  const annotations_1 = require("../utils/annotations");
8
8
  const diagnostics_1 = require("../utils/diagnostics");
9
+ const language_extensions_1 = require("../utils/language-extensions");
9
10
  const lua_ast_1 = require("../utils/lua-ast");
10
11
  const lualib_1 = require("../utils/lualib");
11
12
  const typescript_1 = require("../utils/typescript");
12
13
  const enum_1 = require("./enum");
13
14
  const expression_list_1 = require("./expression-list");
15
+ const call_extension_1 = require("./language-extensions/call-extension");
14
16
  const multi_1 = require("./language-extensions/multi");
15
17
  const optional_chaining_1 = require("./optional-chaining");
16
18
  function addOneToArrayAccessArgument(context, node, index) {
@@ -108,6 +110,15 @@ function transformPropertyAccessExpressionWithCapture(context, node, thisValueCa
108
110
  // If this assumption is no longer true, this may need to be updated.
109
111
  return { expression: builtinResult };
110
112
  }
113
+ if (ts.isIdentifier(node.expression) &&
114
+ node.parent &&
115
+ (!ts.isCallExpression(node.parent) || node.parent.expression !== node)) {
116
+ // Check if this is a method call extension that is not used as a call
117
+ const extensionType = (0, language_extensions_1.getExtensionKindForNode)(context, node);
118
+ if (extensionType && call_extension_1.callExtensions.has(extensionType)) {
119
+ context.diagnostics.push((0, diagnostics_1.invalidCallExtensionUse)(node));
120
+ }
121
+ }
111
122
  const table = context.transformExpression(node.expression);
112
123
  if (thisValueCapture) {
113
124
  const thisValue = (0, optional_chaining_1.captureThisValue)(context, table, thisValueCapture, node.expression);
@@ -3,3 +3,4 @@ import * as lua from "../../LuaAST";
3
3
  import { FunctionVisitor, TransformationContext } from "../context";
4
4
  export declare const transformConditionalExpression: FunctionVisitor<ts.ConditionalExpression>;
5
5
  export declare function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): lua.IfStatement;
6
+ export declare function checkOnlyTruthyCondition(condition: ts.Expression, context: TransformationContext): void;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformIfStatement = exports.transformConditionalExpression = void 0;
3
+ exports.checkOnlyTruthyCondition = exports.transformIfStatement = exports.transformConditionalExpression = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const preceding_statements_1 = require("../utils/preceding-statements");
7
7
  const scope_1 = require("../utils/scope");
8
8
  const block_1 = require("./block");
9
9
  const typescript_1 = require("../utils/typescript");
10
+ const diagnostics_1 = require("../utils/diagnostics");
10
11
  function transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse) {
11
12
  const tempVar = context.createTempNameForNode(expression.condition);
12
13
  const trueStatements = whenTrue[0].concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue[1], expression.whenTrue));
@@ -19,6 +20,8 @@ function transformProtectedConditionalExpression(context, expression, condition,
19
20
  return lua.cloneIdentifier(tempVar);
20
21
  }
21
22
  const transformConditionalExpression = (expression, context) => {
23
+ // Check if we need to add diagnostic about Lua truthiness
24
+ checkOnlyTruthyCondition(expression.condition, context);
22
25
  const condition = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.condition));
23
26
  const whenTrue = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenTrue));
24
27
  const whenFalse = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenFalse));
@@ -35,6 +38,8 @@ const transformConditionalExpression = (expression, context) => {
35
38
  exports.transformConditionalExpression = transformConditionalExpression;
36
39
  function transformIfStatement(statement, context) {
37
40
  context.pushScope(scope_1.ScopeType.Conditional);
41
+ // Check if we need to add diagnostic about Lua truthiness
42
+ checkOnlyTruthyCondition(statement.expression, context);
38
43
  const condition = context.transformExpression(statement.expression);
39
44
  const statements = (0, scope_1.performHoisting)(context, (0, block_1.transformBlockOrStatement)(context, statement.thenStatement));
40
45
  context.popScope();
@@ -70,4 +75,10 @@ function transformIfStatement(statement, context) {
70
75
  return lua.createIfStatement(condition, ifBlock);
71
76
  }
72
77
  exports.transformIfStatement = transformIfStatement;
78
+ function checkOnlyTruthyCondition(condition, context) {
79
+ if (!(0, typescript_1.canBeFalsy)(context, context.checker.getTypeAtLocation(condition))) {
80
+ context.diagnostics.push((0, diagnostics_1.truthyOnlyConditionalValue)(condition));
81
+ }
82
+ }
83
+ exports.checkOnlyTruthyCondition = checkOnlyTruthyCondition;
73
84
  //# sourceMappingURL=conditional.js.map
@@ -28,7 +28,10 @@ function transformNonValueIdentifier(context, identifier, symbol) {
28
28
  : (0, language_extensions_1.getExtensionKindForNode)(context, identifier);
29
29
  if (extensionKind) {
30
30
  if (call_extension_1.callExtensions.has(extensionKind)) {
31
- context.diagnostics.push((0, diagnostics_1.invalidCallExtensionUse)(identifier));
31
+ // Avoid putting duplicate diagnostic on the name of a variable declaration, due to the inferred type
32
+ if (!(ts.isVariableDeclaration(identifier.parent) && identifier.parent.name === identifier)) {
33
+ context.diagnostics.push((0, diagnostics_1.invalidCallExtensionUse)(identifier));
34
+ }
32
35
  // fall through
33
36
  }
34
37
  else if ((0, identifier_1.isIdentifierExtensionValue)(symbol, extensionKind)) {
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformDoStatement = exports.transformWhileStatement = void 0;
4
4
  const lua = require("../../../LuaAST");
5
5
  const preceding_statements_1 = require("../../utils/preceding-statements");
6
+ const conditional_1 = require("../conditional");
6
7
  const utils_1 = require("./utils");
7
8
  const transformWhileStatement = (statement, context) => {
9
+ // Check if we need to add diagnostic about Lua truthiness
10
+ (0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
8
11
  const body = (0, utils_1.transformLoopBody)(context, statement);
9
12
  let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
10
13
  // If condition has preceding statements, ensure they are executed every iteration by using the form:
@@ -25,6 +28,8 @@ const transformWhileStatement = (statement, context) => {
25
28
  };
26
29
  exports.transformWhileStatement = transformWhileStatement;
27
30
  const transformDoStatement = (statement, context) => {
31
+ // Check if we need to add diagnostic about Lua truthiness
32
+ (0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
28
33
  const body = lua.createDoStatement((0, utils_1.transformLoopBody)(context, statement));
29
34
  let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
30
35
  // If condition has preceding statements, ensure they are executed every iteration by using the form:
@@ -66,14 +66,16 @@ function printStackTraceBundleOverride(rootNode) {
66
66
  }
67
67
  exports.printStackTraceBundleOverride = printStackTraceBundleOverride;
68
68
  function getBundleResult(program, files) {
69
+ var _a, _b, _c;
69
70
  const diagnostics = [];
70
71
  const options = program.getCompilerOptions();
71
72
  const bundleFile = (0, utils_1.cast)(options.luaBundle, utils_1.isNonNull);
72
73
  const entryModule = (0, utils_1.cast)(options.luaBundleEntry, utils_1.isNonNull);
73
74
  // Resolve project settings relative to project file.
74
- const resolvedEntryModule = path.resolve((0, transpiler_1.getSourceDir)(program), entryModule);
75
+ const resolvedEntryModule = path.resolve((0, transpiler_1.getProjectRoot)(program), entryModule);
75
76
  const outputPath = path.resolve((0, transpiler_1.getEmitOutDir)(program), bundleFile);
76
- if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) {
77
+ const entryModuleFilePath = (_b = (_a = program.getSourceFile(entryModule)) === null || _a === void 0 ? void 0 : _a.fileName) !== null && _b !== void 0 ? _b : (_c = program.getSourceFile(resolvedEntryModule)) === null || _c === void 0 ? void 0 : _c.fileName;
78
+ if (entryModuleFilePath === undefined) {
77
79
  diagnostics.push((0, diagnostics_1.couldNotFindBundleEntryPoint)(entryModule));
78
80
  }
79
81
  // For each file: ["<module path>"] = function() <lua content> end,
@@ -81,7 +83,7 @@ function getBundleResult(program, files) {
81
83
  // Create ____modules table containing all entries from moduleTableEntries
82
84
  const moduleTable = createModuleTableNode(moduleTableEntries);
83
85
  // return require("<entry module path>")
84
- const entryPoint = `return require(${createModulePath(entryModule, program)}, ...)\n`;
86
+ const entryPoint = `return require(${createModulePath(entryModuleFilePath !== null && entryModuleFilePath !== void 0 ? entryModuleFilePath : entryModule, program)}, ...)\n`;
85
87
  const footers = [];
86
88
  if (options.sourceMapTraceback) {
87
89
  // Generates SourceMapTraceback for the entire file
@@ -631,7 +631,7 @@ declare const LuaMap: (new <K extends AnyNotNil = AnyNotNil, V = any>() => LuaMa
631
631
  * @param V The type of the values stored in the table.
632
632
  */
633
633
  declare interface ReadonlyLuaMap<K extends AnyNotNil = AnyNotNil, V = any> extends LuaPairsIterable<K, V> {
634
- get: LuaTableGetMethod<K, V>;
634
+ get: LuaTableGetMethod<K, V | undefined>;
635
635
  has: LuaTableHasMethod<K>;
636
636
  }
637
637
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typescript-to-lua",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
5
5
  "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
6
6
  "homepage": "https://typescripttolua.github.io/",