Skip to content

Commit 6e0d84f

Browse files
authored
Added Object.keys and Object.assign (#402)
* Added Object.keys and Object.assign * Updated nyc to solve vulnerabilities * Added Object.values * Added Object.entries
1 parent a246177 commit 6e0d84f

File tree

11 files changed

+902
-2120
lines changed

11 files changed

+902
-2120
lines changed

package-lock.json

Lines changed: 707 additions & 2085 deletions
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
@@ -59,7 +59,7 @@
5959
"deep-equal": "^1.0.1",
6060
"fengari": "^0.1.2",
6161
"glob": "^7.1.2",
62-
"nyc": "^11.9.0",
62+
"nyc": "^13.3.0",
6363
"rimraf": "^2.6.3",
6464
"threads": "^0.12.0",
6565
"ts-node": "^7.0.0",

src/Compiler.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,14 @@ export function createStringCompilerProgram(
106106
}
107107
if (filename.indexOf(".d.ts") !== -1) {
108108
if (!libCache[filename]) {
109-
libCache[filename] =
110-
fs.readFileSync(path.join(path.dirname(require.resolve("typescript")), filename)).toString();
109+
const typeScriptDir = path.dirname(require.resolve("typescript"));
110+
const filePath = path.join(typeScriptDir, filename);
111+
if (fs.existsSync(filePath)) {
112+
libCache[filename] = fs.readFileSync(filePath).toString();
113+
} else {
114+
const pathWithLibPrefix = path.join(typeScriptDir, "lib." + filename);
115+
libCache[filename] = fs.readFileSync(pathWithLibPrefix).toString();
116+
}
111117
}
112118
return ts.createSourceFile(filename, libCache[filename], ts.ScriptTarget.Latest, false);
113119
}

src/LuaLib.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export enum LuaLibFeature {
2222
InstanceOf = "InstanceOf",
2323
Iterator = "Iterator",
2424
Map = "Map",
25+
ObjectAssign = "ObjectAssign",
26+
ObjectEntries = "ObjectEntries",
27+
ObjectKeys = "ObjectKeys",
28+
ObjectValues = "ObjectValues",
2529
Set = "Set",
2630
WeakMap = "WeakMap",
2731
WeakSet = "WeakSet",

src/LuaTransformer.ts

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,7 +1754,7 @@ export class LuaTransformer {
17541754
return tstl.createForInStatement(
17551755
block,
17561756
[this.transformIdentifier(statement.initializer.declarations[0].name as ts.Identifier)],
1757-
[this.transformLuaLibFunction(LuaLibFeature.Iterator, iterable)]
1757+
[this.transformLuaLibFunction(LuaLibFeature.Iterator, statement.expression, iterable)]
17581758
);
17591759

17601760
} else {
@@ -1767,7 +1767,7 @@ export class LuaTransformer {
17671767
return tstl.createForInStatement(
17681768
block,
17691769
[valueVariable],
1770-
[this.transformLuaLibFunction(LuaLibFeature.Iterator, iterable)]
1770+
[this.transformLuaLibFunction(LuaLibFeature.Iterator, statement.expression, iterable)]
17711771
);
17721772
}
17731773
}
@@ -2126,7 +2126,7 @@ export class LuaTransformer {
21262126
// Cannot use instanceof on extension classes
21272127
throw TSTLErrors.InvalidInstanceOfExtension(expression);
21282128
}
2129-
return this.transformLuaLibFunction(LuaLibFeature.InstanceOf, lhs, rhs);
2129+
return this.transformLuaLibFunction(LuaLibFeature.InstanceOf, expression, lhs, rhs);
21302130

21312131
case ts.SyntaxKind.CommaToken:
21322132
return this.createImmediatelyInvokedFunctionExpression(
@@ -2831,23 +2831,25 @@ export class LuaTransformer {
28312831
const ownerType = this.checker.getTypeAtLocation(node.expression.expression);
28322832

28332833
if (ownerType.symbol && ownerType.symbol.escapedName === "Math") {
2834-
parameters = this.transformArguments(node.arguments);
28352834
return tstl.createCallExpression(
28362835
this.transformMathExpression(node.expression.name),
2837-
parameters,
2836+
this.transformArguments(node.arguments),
28382837
node
28392838
);
28402839
}
28412840

28422841
if (ownerType.symbol && ownerType.symbol.escapedName === "StringConstructor") {
2843-
parameters = this.transformArguments(node.arguments);
28442842
return tstl.createCallExpression(
28452843
this.transformStringExpression(node.expression.name),
2846-
parameters,
2844+
this.transformArguments(node.arguments),
28472845
node
28482846
);
28492847
}
28502848

2849+
if (ownerType.symbol && ownerType.symbol.escapedName === "ObjectConstructor") {
2850+
return this.transformObjectCallExpression(node);
2851+
}
2852+
28512853
switch (ownerType.flags) {
28522854
case ts.TypeFlags.String:
28532855
case ts.TypeFlags.StringLiteral:
@@ -3167,9 +3169,9 @@ export class LuaTransformer {
31673169
const expressionName = expression.name.escapedText as string;
31683170
switch (expressionName) {
31693171
case "replace":
3170-
return this.transformLuaLibFunction(LuaLibFeature.StringReplace, caller, ...params);
3172+
return this.transformLuaLibFunction(LuaLibFeature.StringReplace, node, caller, ...params);
31713173
case "concat":
3172-
return this.transformLuaLibFunction(LuaLibFeature.StringConcat, caller, ...params);
3174+
return this.transformLuaLibFunction(LuaLibFeature.StringConcat, node, caller, ...params);
31733175
case "indexOf":
31743176
const stringExpression =
31753177
node.arguments.length === 1
@@ -3226,7 +3228,7 @@ export class LuaTransformer {
32263228
case "toUpperCase":
32273229
return this.createStringCall("upper", node, caller);
32283230
case "split":
3229-
return this.transformLuaLibFunction(LuaLibFeature.StringSplit, caller, ...params);
3231+
return this.transformLuaLibFunction(LuaLibFeature.StringSplit, node, caller, ...params);
32303232
case "charAt":
32313233
const firstParamPlusOne = this.expressionPlusOne(params[0]);
32323234
return this.createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne);
@@ -3255,7 +3257,7 @@ export class LuaTransformer {
32553257
}
32563258

32573259
// Transpile a String._ property
3258-
public transformStringExpression(identifier: ts.Identifier): tstl.TableIndexExpression {
3260+
public transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult {
32593261
const identifierString = identifier.escapedText as string;
32603262

32613263
switch (identifierString) {
@@ -3273,46 +3275,71 @@ export class LuaTransformer {
32733275
}
32743276
}
32753277

3278+
// Transpile an Object._ property
3279+
public transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult {
3280+
const method = expression.expression as ts.PropertyAccessExpression;
3281+
const parameters = this.transformArguments(expression.arguments);
3282+
const caller = this.transformExpression(expression.expression);
3283+
const methodName = method.name.escapedText;
3284+
3285+
switch (methodName) {
3286+
case "assign":
3287+
return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...parameters);
3288+
case "entries":
3289+
return this.transformLuaLibFunction(LuaLibFeature.ObjectEntries, expression, ...parameters);
3290+
case "keys":
3291+
return this.transformLuaLibFunction(LuaLibFeature.ObjectKeys, expression, ...parameters);
3292+
case "values":
3293+
return this.transformLuaLibFunction(LuaLibFeature.ObjectValues, expression, ...parameters);
3294+
default:
3295+
throw TSTLErrors.UnsupportedForTarget(
3296+
`object property ${methodName}`,
3297+
this.options.luaTarget,
3298+
expression
3299+
);
3300+
}
3301+
}
3302+
32763303
public transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression {
32773304
const expression = node.expression as ts.PropertyAccessExpression;
32783305
const params = this.transformArguments(node.arguments);
32793306
const caller = this.transformExpression(expression.expression);
32803307
const expressionName = expression.name.escapedText;
32813308
switch (expressionName) {
32823309
case "concat":
3283-
return this.transformLuaLibFunction(LuaLibFeature.ArrayConcat, caller, ...params);
3310+
return this.transformLuaLibFunction(LuaLibFeature.ArrayConcat, node, caller, ...params);
32843311
case "push":
3285-
return this.transformLuaLibFunction(LuaLibFeature.ArrayPush, caller, ...params);
3312+
return this.transformLuaLibFunction(LuaLibFeature.ArrayPush, node, caller, ...params);
32863313
case "reverse":
3287-
return this.transformLuaLibFunction(LuaLibFeature.ArrayReverse, caller);
3314+
return this.transformLuaLibFunction(LuaLibFeature.ArrayReverse, node, caller);
32883315
case "shift":
3289-
return this.transformLuaLibFunction(LuaLibFeature.ArrayShift, caller);
3316+
return this.transformLuaLibFunction(LuaLibFeature.ArrayShift, node, caller);
32903317
case "unshift":
3291-
return this.transformLuaLibFunction(LuaLibFeature.ArrayUnshift, caller, ...params);
3318+
return this.transformLuaLibFunction(LuaLibFeature.ArrayUnshift, node, caller, ...params);
32923319
case "sort":
3293-
return this.transformLuaLibFunction(LuaLibFeature.ArraySort, caller);
3320+
return this.transformLuaLibFunction(LuaLibFeature.ArraySort, node, caller);
32943321
case "pop":
32953322
return tstl.createCallExpression(
32963323
tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("remove")),
32973324
[caller],
32983325
node
32993326
);
33003327
case "forEach":
3301-
return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, caller, ...params);
3328+
return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, node, caller, ...params);
33023329
case "indexOf":
3303-
return this.transformLuaLibFunction(LuaLibFeature.ArrayIndexOf, caller, ...params);
3330+
return this.transformLuaLibFunction(LuaLibFeature.ArrayIndexOf, node, caller, ...params);
33043331
case "map":
3305-
return this.transformLuaLibFunction(LuaLibFeature.ArrayMap, caller, ...params);
3332+
return this.transformLuaLibFunction(LuaLibFeature.ArrayMap, node, caller, ...params);
33063333
case "filter":
3307-
return this.transformLuaLibFunction(LuaLibFeature.ArrayFilter, caller, ...params);
3334+
return this.transformLuaLibFunction(LuaLibFeature.ArrayFilter, node, caller, ...params);
33083335
case "some":
3309-
return this.transformLuaLibFunction(LuaLibFeature.ArraySome, caller, ...params);
3336+
return this.transformLuaLibFunction(LuaLibFeature.ArraySome, node, caller, ...params);
33103337
case "every":
3311-
return this.transformLuaLibFunction(LuaLibFeature.ArrayEvery, caller, ...params);
3338+
return this.transformLuaLibFunction(LuaLibFeature.ArrayEvery, node, caller, ...params);
33123339
case "slice":
3313-
return this.transformLuaLibFunction(LuaLibFeature.ArraySlice, caller, ...params);
3340+
return this.transformLuaLibFunction(LuaLibFeature.ArraySlice, node, caller, ...params);
33143341
case "splice":
3315-
return this.transformLuaLibFunction(LuaLibFeature.ArraySplice, caller, ...params);
3342+
return this.transformLuaLibFunction(LuaLibFeature.ArraySplice, node, caller, ...params);
33163343
case "join":
33173344
const parameters = node.arguments.length === 0
33183345
? [caller, tstl.createStringLiteral(",")]
@@ -3339,11 +3366,11 @@ export class LuaTransformer {
33393366
const expressionName = expression.name.escapedText;
33403367
switch (expressionName) {
33413368
case "apply":
3342-
return this.transformLuaLibFunction(LuaLibFeature.FunctionApply, caller, ...params);
3369+
return this.transformLuaLibFunction(LuaLibFeature.FunctionApply, node, caller, ...params);
33433370
case "bind":
3344-
return this.transformLuaLibFunction(LuaLibFeature.FunctionBind, caller, ...params);
3371+
return this.transformLuaLibFunction(LuaLibFeature.FunctionBind, node, caller, ...params);
33453372
case "call":
3346-
return this.transformLuaLibFunction(LuaLibFeature.FunctionCall, caller, ...params);
3373+
return this.transformLuaLibFunction(LuaLibFeature.FunctionCall, node, caller, ...params);
33473374
default:
33483375
throw TSTLErrors.UnsupportedProperty("function", expressionName as string, node);
33493376
}
@@ -3526,10 +3553,15 @@ export class LuaTransformer {
35263553
tstl.createStringLiteral(identifier.text));
35273554
}
35283555

3529-
public transformLuaLibFunction(func: LuaLibFeature, ...params: tstl.Expression[]): tstl.CallExpression {
3556+
public transformLuaLibFunction(
3557+
func: LuaLibFeature,
3558+
tsParent: ts.Expression,
3559+
...params: tstl.Expression[]
3560+
): tstl.CallExpression
3561+
{
35303562
this.importLuaLibFeature(func);
35313563
const functionIdentifier = tstl.createIdentifier(`__TS__${func}`);
3532-
return tstl.createCallExpression(functionIdentifier, params);
3564+
return tstl.createCallExpression(functionIdentifier, params, tsParent);
35333565
}
35343566

35353567
public checkForLuaLibType(type: ts.Type): void {

src/TSHelper.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as ts from "typescript";
22

33
import {Decorator, DecoratorKind} from "./Decorator";
44
import * as tstl from "./LuaAST";
5-
import {TSTLErrors} from "./TSTLErrors";
65

76
export enum ContextType {
87
None,

src/lualib/ObjectAssign.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// https://tc39.github.io/ecma262/#sec-object.assign
2+
function __TS__ObjectAssign<T extends object>(to: T, ...sources: object[]): T {
3+
if (to === undefined) {
4+
return to;
5+
}
6+
7+
for (const source of sources) {
8+
for (const key in source) {
9+
to[key] = source[key];
10+
}
11+
}
12+
13+
return to;
14+
}

src/lualib/ObjectEntries.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function __TS__ObjectEntries(obj: any): Array<string | number> {
2+
const result = [];
3+
for (const key in obj) {
4+
result[result.length] = [key, obj[key]];
5+
}
6+
return result;
7+
}

src/lualib/ObjectKeys.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function __TS__ObjectKeys(obj: any): Array<string | number> {
2+
const result = [];
3+
for (const key in obj) {
4+
result[result.length] = key;
5+
}
6+
return result;
7+
}

src/lualib/ObjectValues.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function __TS__ObjectValues(obj: any): Array<string | number> {
2+
const result = [];
3+
for (const key in obj) {
4+
result[result.length] = obj[key];
5+
}
6+
return result;
7+
}

0 commit comments

Comments
 (0)