Skip to content

Dots in module path breaks Lua import in a non-bundle compilation #1445

@Renegatto

Description

@Renegatto

Abstract

tstl fails to produce valid lua code from a subset of valid (accordingly to tstl docs) code if ts file names contain dots in paths.

This problem may naturally arise, for example, when compiling from Purescript to JS and then from JS to Lua using tstl.

The example is not the natural use case for tstl, however, the bug is the bug.

Example

Let's say we have two files:
./src/Foo.Bar/index.ts

export const answer: number = 42;

./src/Qux/index.ts

import {answer} from "./Foo.Bar";
export const printAnswer = () => print(answer)

So import {answer} from "./Foo.Bar"; will be compiled (in a non-bundle mode) to

local ____Foo_2EBar = require("Foo.Bar.index")
local answer = ____Foo_2EBar.answer

and lua will be searching at ./Foo/Bar/index.lua" for that module.

That will result an error:

lua: ./Qux/index.lua:3: module 'Foo.Bar.index' not found:
        no field package.preload['Foo.Bar.index']
        no file './Foo/Bar/index.lua'
        no file '/usr/local/share/lua/5.1/Foo/Bar/index.lua'
        no file '/usr/local/share/lua/5.1/Foo/Bar/index/init.lua'
        no file '/usr/local/lib/lua/5.1/Foo/Bar/index.lua'
        no file '/usr/local/lib/lua/5.1/Foo/Bar/index/init.lua'
        no file '/usr/share/lua/5.1/Foo/Bar/index.lua'
        no file '/usr/share/lua/5.1/Foo/Bar/index/init.lua'
        no file './Foo/Bar/index.so'
        no file '/usr/local/lib/lua/5.1/Foo/Bar/index.so'
        no file '/usr/lib/x86_64-linux-gnu/lua/5.1/Foo/Bar/index.so'
        no file '/usr/lib/lua/5.1/Foo/Bar/index.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
        no file './Foo.so'
        no file '/usr/local/lib/lua/5.1/Foo.so'
        no file '/usr/lib/x86_64-linux-gnu/lua/5.1/Foo.so'
        no file '/usr/lib/lua/5.1/Foo.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
        [C]: in function 'require'
        ./Qux/index.lua:3: in main chunk
        [C]: in function 'require'
        ./main.lua:3: in main chunk
        [C]: ?

Soulution

When compiled to a file ./dist/Foo.Bar.Baz/index.lua, split it's name by dots (excluding extension) and put the file into directory ./Foo/Bar/Baz.
This will fix module resolution for lua.
So basically the ts directory

.
├── Foo/
│   └── index.ts
├── Foo.Bar/
│   └── index.ts
├── Foo.Bar.Baz/
│   └── index.ts
├── Qux/
│   └── index.ts
└── index.ts

should be compiled into

.
├── Foo/
│   ├── index.lua
│   └── Bar/
│       └── index.lua
│       └── Baz/
│           └── index.lua
├── Qux/
│   └── index.lua
└── index.lua

instead of

.
├── Foo/
│   └── index.lua
├── Foo.Bar/
│   └── index.lua
├── Foo.Bar.Baz/
│   └── index.lua
├── Qux/
│   └── index.lua
└── index.lua

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugscope: transpileAny transpilation not directly related to code transforms

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions