From 8dcda03a39947c33ab17344981fd486c2d81db9a Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 27 Mar 2019 08:38:14 +0500 Subject: [PATCH] Add Object.fromEntries --- src/LuaLib.ts | 2 ++ src/LuaTransformer.ts | 2 ++ src/lualib/ObjectFromEntries.ts | 24 ++++++++++++++++++++ test/unit/lualib/lualib.spec.ts | 39 ++++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/lualib/ObjectFromEntries.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 3db60196c..e3e2f006f 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -29,6 +29,7 @@ export enum LuaLibFeature { NewIndex = "NewIndex", ObjectAssign = "ObjectAssign", ObjectEntries = "ObjectEntries", + ObjectFromEntries = "ObjectFromEntries", ObjectKeys = "ObjectKeys", ObjectValues = "ObjectValues", Set = "Set", @@ -43,6 +44,7 @@ export enum LuaLibFeature { const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { Iterator: [LuaLibFeature.Symbol], + ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 97b789989..c673df38f 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3707,6 +3707,8 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...parameters); case "entries": return this.transformLuaLibFunction(LuaLibFeature.ObjectEntries, expression, ...parameters); + case "fromEntries": + return this.transformLuaLibFunction(LuaLibFeature.ObjectFromEntries, expression, ...parameters); case "keys": return this.transformLuaLibFunction(LuaLibFeature.ObjectKeys, expression, ...parameters); case "values": diff --git a/src/lualib/ObjectFromEntries.ts b/src/lualib/ObjectFromEntries.ts new file mode 100644 index 000000000..efdf7dd90 --- /dev/null +++ b/src/lualib/ObjectFromEntries.ts @@ -0,0 +1,24 @@ +function __TS__ObjectFromEntries( + this: void, + entries: ReadonlyArray<[string, T]> | Iterable<[string, T]> +): Record { + const obj: Record = {}; + + const iterable = entries as Iterable<[string, T]>; + if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) break; + + const value: [string, T] = result.value; + obj[value[0]] = value[1]; + } + } else { + for (const entry of entries as ReadonlyArray<[string, T]>) { + obj[entry[0]] = entry[1]; + } + } + + return obj; +} diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 8c4052562..5caa5cbaa 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -408,7 +408,7 @@ test.each([ { initial: "{}", parameters: "{a: 3}", expected: { a: 3 } }, { initial: "{a: 3}", parameters: "{a: 5}", expected: { a: 5 } }, { initial: "{a: 3}", parameters: "{b: 5},{c: 7}", expected: { a: 3, b: 5, c: 7 } }, -])("Object.Assign (%p)", ({ initial, parameters, expected }) => { +])("Object.assign (%p)", ({ initial, parameters, expected }) => { const jsonResult = util.transpileAndExecute(` return JSONStringify(Object.assign(${initial},${parameters})); `); @@ -484,3 +484,40 @@ test.each([ } } }); + +// https://github.com/Microsoft/TypeScript/pull/26149 +const objectFromEntriesDeclaration = ` + interface ObjectConstructor { + fromEntries(entries: ReadonlyArray<[string, T]> | Iterable<[string, T]>): Record; + fromEntries(entries: ReadonlyArray<[string, any]> | Iterable<[string, any]>): Record; + } +`; + +test.each([ + { entries: [], expected: [] }, + { entries: [["a", 1], ["b", 2]], expected: { a: 1, b: 2 } }, + { entries: [["a", 1], ["a", 2]], expected: { a: 2 } }, +])("Object.fromEntries (%p)", ({ entries, expected }) => { + const result = util.transpileAndExecute( + `const obj = Object.fromEntries(${JSON.stringify(entries)}); + return JSONStringify(obj);`, + undefined, + undefined, + objectFromEntriesDeclaration, + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test("Object.fromEntries (Map)", () => { + const result = util.transpileAndExecute( + `const map = new Map([["foo", "bar"]]); + const obj = Object.fromEntries(map); + return JSONStringify(obj);`, + undefined, + undefined, + objectFromEntriesDeclaration, + ); + + expect(JSON.parse(result)).toEqual({ foo: "bar" }); +});