Skip to content

Commit a0fd091

Browse files
committed
Merge remote-tracking branch 'upstream/master' into node-module-resolution
2 parents 052ac1f + ccf95d7 commit a0fd091

38 files changed

Lines changed: 716 additions & 215 deletions

.devcontainer/devcontainer.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "TypeScriptToLua",
3+
"image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14",
4+
"settings": {
5+
"terminal.integrated.shell.linux": "/bin/bash"
6+
},
7+
"extensions": [
8+
"ark120202.vscode-typescript-to-lua",
9+
"dbaeumer.vscode-eslint",
10+
"editorconfig.editorconfig",
11+
"esbenp.prettier-vscode"
12+
],
13+
"postCreateCommand": "npm ci"
14+
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typescript-to-lua",
3-
"version": "0.35.0",
3+
"version": "0.36.0",
44
"description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
55
"repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
66
"license": "MIT",

src/LuaAST.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
// because we don't create the AST from text
66

77
import * as ts from "typescript";
8+
import { LuaLibFeature } from "./transformation/utils/lualib";
89
import { castArray } from "./utils";
910

1011
export enum SyntaxKind {
12+
File,
1113
Block,
1214

1315
// Statements
@@ -186,6 +188,30 @@ export function getOriginalPos(node: Node): TextRange {
186188
return { line: node.line, column: node.column };
187189
}
188190

191+
export interface File extends Node {
192+
kind: SyntaxKind.File;
193+
statements: Statement[];
194+
luaLibFeatures: Set<LuaLibFeature>;
195+
trivia: string;
196+
}
197+
198+
export function isFile(node: Node): node is File {
199+
return node.kind === SyntaxKind.File;
200+
}
201+
202+
export function createFile(
203+
statements: Statement[],
204+
luaLibFeatures: Set<LuaLibFeature>,
205+
trivia: string,
206+
tsOriginal?: ts.Node
207+
): File {
208+
const file = createNode(SyntaxKind.File, tsOriginal) as File;
209+
file.statements = statements;
210+
file.luaLibFeatures = luaLibFeatures;
211+
file.trivia = trivia;
212+
return file;
213+
}
214+
189215
export interface Block extends Node {
190216
kind: SyntaxKind.Block;
191217
statements: Statement[];

src/LuaLib.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ export enum LuaLibFeature {
2828
ArraySetLength = "ArraySetLength",
2929
Class = "Class",
3030
ClassExtends = "ClassExtends",
31+
CloneDescriptor = "CloneDescriptor",
3132
Decorate = "Decorate",
32-
Descriptors = "Descriptors",
33+
DecorateParam = "DecorateParam",
34+
Delete = "Delete",
35+
DelegatedYield = "DelegatedYield",
3336
Error = "Error",
3437
FunctionBind = "FunctionBind",
3538
Generator = "Generator",
@@ -44,14 +47,18 @@ export enum LuaLibFeature {
4447
NumberIsNaN = "NumberIsNaN",
4548
NumberToString = "NumberToString",
4649
ObjectAssign = "ObjectAssign",
50+
ObjectDefineProperty = "ObjectDefineProperty",
4751
ObjectEntries = "ObjectEntries",
4852
ObjectFromEntries = "ObjectFromEntries",
53+
ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor",
54+
ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors",
4955
ObjectKeys = "ObjectKeys",
5056
ObjectRest = "ObjectRest",
5157
ObjectValues = "ObjectValues",
5258
ParseFloat = "ParseFloat",
5359
ParseInt = "ParseInt",
5460
Set = "Set",
61+
SetDescriptor = "SetDescriptor",
5562
WeakMap = "WeakMap",
5663
WeakSet = "WeakSet",
5764
SourceMapTraceBack = "SourceMapTraceBack",
@@ -81,11 +88,14 @@ export enum LuaLibFeature {
8188
const luaLibDependencies: Partial<Record<LuaLibFeature, LuaLibFeature[]>> = {
8289
ArrayFlat: [LuaLibFeature.ArrayConcat],
8390
ArrayFlatMap: [LuaLibFeature.ArrayConcat],
91+
Decorate: [LuaLibFeature.CloneDescriptor],
92+
Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors],
8493
Error: [LuaLibFeature.New, LuaLibFeature.Class],
8594
FunctionBind: [LuaLibFeature.Unpack],
8695
Generator: [LuaLibFeature.Symbol],
8796
InstanceOf: [LuaLibFeature.Symbol],
8897
Iterator: [LuaLibFeature.Symbol],
98+
ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor],
8999
ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol],
90100
Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class],
91101
Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class],

src/LuaPrinter.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,7 @@ function isSimpleExpression(expression: lua.Expression): boolean {
8585

8686
type SourceChunk = string | SourceNode;
8787

88-
export type Printer = (
89-
program: ts.Program,
90-
host: TranspilerHost,
91-
fileName: string,
92-
block: lua.Block,
93-
luaLibFeatures: Set<LuaLibFeature>
94-
) => SourceNode;
88+
export type Printer = (program: ts.Program, host: TranspilerHost, fileName: string, file: lua.File) => SourceNode;
9589

9690
export class LuaPrinter {
9791
private static operatorMap: Record<lua.Operator, string> = {
@@ -146,7 +140,7 @@ export class LuaPrinter {
146140
}
147141
}
148142

149-
public print(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>): SourceNode {
143+
public print(file: lua.File): SourceNode {
150144
let header = "";
151145

152146
if (!this.options.noHeader) {
@@ -155,20 +149,20 @@ export class LuaPrinter {
155149

156150
// Add traceback lualib if sourcemap traceback option is enabled
157151
if (this.options.sourceMapTraceback) {
158-
luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack);
152+
file.luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack);
159153
}
160154

161155
const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require;
162156
if (
163157
luaLibImport === LuaLibImportKind.Always ||
164-
(luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0)
158+
(luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0)
165159
) {
166160
// Require lualib bundle
167161
header += 'require(__TS__Resolve("<internal>/lualib_bundle"));\n';
168-
} else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) {
162+
} else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) {
169163
// Inline lualib features
170164
header += "-- Lua Library inline imports\n";
171-
header += loadLuaLibFeatures(luaLibFeatures, this.host);
165+
header += loadLuaLibFeatures(file.luaLibFeatures, this.host);
172166
}
173167

174168
if (this.options.sourceMapTraceback) {
@@ -177,9 +171,8 @@ export class LuaPrinter {
177171

178172
// Hack: __TS__Resolve macro resolution destroys mappings of macro's node grand-parent
179173
const headerNode = new SourceNode(null, null, null, new SourceNode(null, null, null, header));
180-
const fileBlockNode = this.printBlock(block);
181174

182-
return this.concatNodes(headerNode, fileBlockNode);
175+
return this.concatNodes(headerNode, ...this.printStatementArray(file.statements));
183176
}
184177

185178
protected pushIndent(): void {

src/lualib/CloneDescriptor.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function __TS__CloneDescriptor(
2+
this: void,
3+
{ enumerable, configurable, get, set, writable, value }: PropertyDescriptor
4+
): PropertyDescriptor {
5+
const descriptor: PropertyDescriptor = {
6+
enumerable: enumerable === true,
7+
configurable: configurable === true,
8+
};
9+
10+
const hasGetterOrSetter = get !== undefined || set !== undefined;
11+
const hasValueOrWritableAttribute = writable !== undefined || value !== undefined;
12+
13+
if (hasGetterOrSetter && hasValueOrWritableAttribute) {
14+
throw "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.";
15+
}
16+
17+
if (get || set) {
18+
descriptor.get = get;
19+
descriptor.set = set;
20+
} else {
21+
descriptor.value = value;
22+
descriptor.writable = writable === true;
23+
}
24+
25+
return descriptor;
26+
}

src/lualib/Decorate.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598
33
*/
4-
function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: string, desc?: any): {} {
4+
function __TS__Decorate(this: void, decorators: Function[], target: any, key?: any, desc?: any): {} {
55
let result = target;
66

77
for (let i = decorators.length; i >= 0; i--) {
@@ -11,8 +11,22 @@ function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: st
1111

1212
if (key === undefined) {
1313
result = decorator(result);
14-
} else if (desc !== undefined) {
15-
result = decorator(target, key, result);
14+
} else if (desc === true) {
15+
const value = rawget(target, key);
16+
const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) || {
17+
configurable: true,
18+
writable: true,
19+
value,
20+
};
21+
const desc = decorator(target, key, descriptor) || descriptor;
22+
const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set;
23+
if (isSimpleValue) {
24+
rawset(target, key, desc.value);
25+
} else {
26+
__TS__SetDescriptor(target, key, { ...descriptor, ...desc });
27+
}
28+
} else if (desc === false) {
29+
result = decorator(target, key, desc);
1630
} else {
1731
result = decorator(target, key);
1832
}

src/lualib/DecorateParam.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function __TS__DecorateParam(this: void, paramIndex: number, decorator: Function): {} {
2+
return (target: Function, key?: string) => decorator(target, key, paramIndex);
3+
}

src/lualib/DelegatedYield.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function __TS__DelegatedYield<T>(this: void, iterable: string | GeneratorIterator | Iterable<T> | readonly T[]) {
2+
if (typeof iterable === "string") {
3+
for (const index of forRange(0, iterable.length - 1)) {
4+
coroutine.yield(iterable[index]);
5+
}
6+
} else if ("____coroutine" in iterable) {
7+
const co = iterable.____coroutine;
8+
while (true) {
9+
const [status, value] = coroutine.resume(co);
10+
if (!status) throw value;
11+
if (coroutine.status(co) === "dead") {
12+
return value;
13+
} else {
14+
coroutine.yield(value);
15+
}
16+
}
17+
} else if (iterable[Symbol.iterator]) {
18+
const iterator = iterable[Symbol.iterator]();
19+
while (true) {
20+
const result = iterator.next();
21+
if (result.done) {
22+
return result.value;
23+
} else {
24+
coroutine.yield(result.value);
25+
}
26+
}
27+
} else {
28+
for (const value of iterable as readonly T[]) {
29+
coroutine.yield(value);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)