diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index a4144e126..172687da3 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "./CompilerOptions"; -import { DecoratorKind } from "./Decorator"; +import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import { LuaLibFeature } from "./LuaLib"; import { ContextType, TSHelper as tsHelper } from "./TSHelper"; @@ -357,11 +357,21 @@ export class LuaTransformer { scope.importStatements = []; } + let shouldResolve = true; + const moduleOwnerSymbol = this.checker.getSymbolAtLocation(statement.moduleSpecifier); + if (moduleOwnerSymbol) { + const decorators = new Map(); + tsHelper.collectCustomDecorators(moduleOwnerSymbol, this.checker, decorators); + if (decorators.has(DecoratorKind.NoResolution)) { + shouldResolve = false; + } + } + const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; const importPath = moduleSpecifier.text.replace(new RegExp('"', "g"), ""); + const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); if (!statement.importClause) { - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); result.push(tstl.createExpressionStatement(requireCall)); if (scope.importStatements) { scope.importStatements.push(...result); @@ -376,10 +386,6 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedImportType(statement.importClause); } - const type = this.checker.getTypeAtLocation(imports); - const shouldResolve = !tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.NoResolution); - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); - if (ts.isNamedImports(imports)) { const filteredElements = imports.elements.filter(e => { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index b6db8f877..3f864b3fc 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -91,20 +91,92 @@ test.each([ } ); -test.each([{ comment: "", expectedPath: "src.fake" }, { comment: "/** @noResolution */", expectedPath: "fake" }])( - "noResolution on ambient modules causes no path alterations (%p)", - ({ comment, expectedPath }) => { - const lua = util.transpileString({ - "src/main.ts": `import * as fake from "fake"; fake;`, - "module.d.ts": `${comment} declare module "fake" {}`, - }); - const match = requireRegex.exec(lua); +test.each([ + { + declarationStatement: ` + declare module 'fake' {} + `, + mainCode: "import * as fake from 'fake'; fake;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' {} + `, + mainCode: "import * as fake from 'fake'; fake;", + expectedPath: "fake", + }, + { + declarationStatement: ` + declare module 'fake' { + export const x: number; + } + `, + mainCode: "import { x } from 'fake'; x;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' { + export const x: number; + } + `, + mainCode: "import { x } from 'fake'; x;", + expectedPath: "fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' { + export const x: number; + } + declare module 'fake' { + export const y: number; + } + `, + mainCode: "import { y } from 'fake'; y;", + expectedPath: "fake", + }, + { + declarationStatement: ` + declare module 'fake' { + export const x: number; + } + declare module 'fake' { + export const y: number; + } + `, + mainCode: "import { y } from 'fake'; y;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + declare module 'fake' {} + `, + mainCode: "import 'fake';", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' {} + `, + mainCode: "import 'fake';", + expectedPath: "fake", + }, +])("noResolution prevents any module path resolution behaviour", ({ declarationStatement, mainCode, expectedPath }) => { + const lua = util.transpileString({ + "src/main.ts": mainCode, + "module.d.ts": declarationStatement, + }); + const match = requireRegex.exec(lua); - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe(expectedPath); - } + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe(expectedPath); } -); +}); test("ImportEquals declaration require", () => { const input = `import foo = require("./foo/bar"); foo;`;