Skip to content

Commit 39480bb

Browse files
authored
Add new option to bypass 5.1 try/catch in async/await precaution (#1247)
* Add new option to bypass 5.1 try/catch in async/await precaution * Fix diagnostic tests * Remove unused import
1 parent 4443063 commit 39480bb

File tree

5 files changed

+48
-12
lines changed

5 files changed

+48
-12
lines changed

src/CompilerOptions.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface LuaPluginImport {
2121
[option: string]: any;
2222
}
2323

24-
export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> & {
24+
export interface TypeScriptToLuaOptions {
2525
buildMode?: BuildMode;
2626
extension?: string;
2727
luaBundle?: string;
@@ -35,8 +35,13 @@ export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> & {
3535
plugins?: Array<ts.PluginImport | TransformerImport>;
3636
sourceMapTraceback?: boolean;
3737
tstlVerbose?: boolean;
38-
[option: string]: any;
39-
};
38+
lua51AllowTryCatchInAsyncAwait?: boolean;
39+
}
40+
41+
export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> &
42+
TypeScriptToLuaOptions & {
43+
[option: string]: any;
44+
};
4045

4146
export enum LuaLibImportKind {
4247
None = "none",

src/cli/parse.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ export const optionDeclarations: CommandLineOption[] = [
8888
description: "An array of paths that tstl should not resolve and keep as-is.",
8989
type: "array",
9090
},
91+
{
92+
name: "lua51AllowTryCatchInAsyncAwait",
93+
description: "Always allow try/catch in async/await functions for Lua 5.1.",
94+
type: "boolean",
95+
},
9196
];
9297

9398
export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine {

src/transformation/utils/diagnostics.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as ts from "typescript";
2-
import { LuaTarget } from "../../CompilerOptions";
2+
import { LuaTarget, TypeScriptToLuaOptions } from "../../CompilerOptions";
33
import { createSerialDiagnosticFactory } from "../../utils";
44
import { AnnotationKind } from "./annotations";
55

@@ -84,12 +84,23 @@ export const unsupportedRightShiftOperator = createErrorDiagnosticFactory(
8484
"Right shift operator is not supported for target Lua 5.3. Use `>>>` instead."
8585
);
8686

87+
type NonUniversalTarget = Exclude<LuaTarget, LuaTarget.Universal>;
88+
8789
const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`);
8890
export const unsupportedForTarget = createErrorDiagnosticFactory(
89-
(functionality: string, version: Exclude<LuaTarget, LuaTarget.Universal>) =>
91+
(functionality: string, version: NonUniversalTarget) =>
9092
`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`
9193
);
9294

95+
export const unsupportedForTargetButOverrideAvailable = createErrorDiagnosticFactory(
96+
(functionality: string, version: NonUniversalTarget, optionName: keyof TypeScriptToLuaOptions) =>
97+
`As a precaution, ${functionality} is/are not supported for target ${getLuaTargetName(
98+
version
99+
)} due to language features/limitations. ` +
100+
`However "--${optionName}" can be used to bypass this precaution. ` +
101+
"See https://typescripttolua.github.io/docs/configuration for more information."
102+
);
103+
93104
export const unsupportedProperty = createErrorDiagnosticFactory(
94105
(parentName: string, property: string) => `${parentName}.${property} is unsupported.`
95106
);

src/transformation/visitors/errors.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as ts from "typescript";
22
import { LuaTarget } from "../..";
33
import * as lua from "../../LuaAST";
44
import { FunctionVisitor } from "../context";
5-
import { unsupportedForTarget } from "../utils/diagnostics";
5+
import { unsupportedForTarget, unsupportedForTargetButOverrideAvailable } from "../utils/diagnostics";
66
import { createUnpackCall } from "../utils/lua-ast";
77
import { ScopeType } from "../utils/scope";
88
import { isInAsyncFunction, isInGeneratorFunction } from "../utils/typescript";
@@ -14,8 +14,19 @@ import { createReturnStatement } from "./return";
1414
export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statement, context) => {
1515
const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try);
1616

17-
if (context.options.luaTarget === LuaTarget.Lua51 && isInAsyncFunction(statement)) {
18-
context.diagnostics.push(unsupportedForTarget(statement, "try/catch inside async functions", LuaTarget.Lua51));
17+
if (
18+
context.options.luaTarget === LuaTarget.Lua51 &&
19+
isInAsyncFunction(statement) &&
20+
!context.options.lua51AllowTryCatchInAsyncAwait
21+
) {
22+
context.diagnostics.push(
23+
unsupportedForTargetButOverrideAvailable(
24+
statement,
25+
"try/catch inside async functions",
26+
LuaTarget.Lua51,
27+
"lua51AllowTryCatchInAsyncAwait"
28+
)
29+
);
1930
return tryBlock.statements;
2031
}
2132

test/unit/builtins/async-await.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ModuleKind, ScriptTarget } from "typescript";
22
import { LuaTarget } from "../../../src";
3-
import { awaitMustBeInAsyncFunction, unsupportedForTarget } from "../../../src/transformation/utils/diagnostics";
3+
import { unsupportedForTargetButOverrideAvailable } from "../../../src/transformation/utils/diagnostics";
4+
import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics";
45
import * as util from "../../util";
56

67
const promiseTestLib = `
@@ -540,7 +541,8 @@ describe("try/catch in async function", () => {
540541
// Cannot execute LuaJIT with test runner
541542
{
542543
...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: 4 })),
543-
[LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]),
544+
[LuaTarget.Lua51]: builder =>
545+
builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]),
544546
}
545547
);
546548

@@ -563,7 +565,8 @@ describe("try/catch in async function", () => {
563565
...util.expectEachVersionExceptJit(builder =>
564566
builder.expectToEqual({ reason: "an error occurred in the async function: test error" })
565567
),
566-
[LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]),
568+
[LuaTarget.Lua51]: builder =>
569+
builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]),
567570
}
568571
);
569572

@@ -590,7 +593,8 @@ describe("try/catch in async function", () => {
590593
...util.expectEachVersionExceptJit(builder =>
591594
builder.expectToEqual({ reason: "an error occurred in the async function: test error" })
592595
),
593-
[LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]),
596+
[LuaTarget.Lua51]: builder =>
597+
builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]),
594598
}
595599
);
596600
});

0 commit comments

Comments
 (0)