From 8a1fcf1fe68b2dd119b9b521863aabdf3457406d Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 14 Apr 2019 08:09:49 -0600 Subject: [PATCH] Fixed merging module into interface --- src/LuaTransformer.ts | 13 +++++++++---- test/unit/modules.spec.ts | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index eede8ed9e..ccb629938 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1300,10 +1300,15 @@ export class LuaTransformer { const symbol = this.checker.getSymbolAtLocation(statement.name); const hasExports = symbol !== undefined && this.checker.getExportsOfModule(symbol).length > 0; - const isFirstDeclaration = symbol !== undefined - && symbol.declarations[0] === statement - // TS allows an empty namespace before a class of the same name - && symbol.declarations.findIndex(d => ts.isClassLike(d)) === -1; + + // This is NOT the first declaration if: + // - declared as a module before this (ignore interfaces with same name) + // - declared as a class or function at all (TS requires these to be before module, unless module is empty) + const isFirstDeclaration = + symbol === undefined + || (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 + && statement === symbol.declarations.find(ts.isModuleDeclaration)); + if (isFirstDeclaration) { const isExported = (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; if (isExported && this.currentNamespace) { diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index c02f052de..6da420d9e 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -63,3 +63,13 @@ test("Access this in module", () => { const code = `return M.bar();`; expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); }); + +test("Module merged with interface", () => { + const header = ` + interface Foo {} + module Foo { + export function bar() { return "foobar"; } + }`; + const code = `return Foo.bar();`; + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); +});