Skip to content

Absolute import path slashes normalized#390

Merged
Perryvw merged 15 commits intoTypeScriptToLua:masterfrom
hazzard993:import-path-windows-fix
Feb 18, 2019
Merged

Absolute import path slashes normalized#390
Perryvw merged 15 commits intoTypeScriptToLua:masterfrom
hazzard993:import-path-windows-fix

Conversation

@hazzard993
Copy link
Copy Markdown
Contributor

I've noticed getImportPath will create absolutePathToImport which contains backslashes on Windows.

rootDir seems to always use forward slashes.

So when this happens:

absolutePathToImport.replace(this.options.rootDir, "").slice(1)

rootDir may not be subtracted from aboluteImportPath correctly.

This results in something like:

local __TSTL_Player = require(":.Users.hazzard993.Desktop.test.src.Player");

This PR is just to ensure that absolutePathToImport contains forward slashes to correct the require path when rootDir is used.

@Perryvw
Copy link
Copy Markdown
Member

Perryvw commented Feb 10, 2019

Could you add a couple tests for this? You can probably do something like:

util.transpileString(`import * from "somePath";`, { rootPath: "Test/Root/Path" })

@hazzard993
Copy link
Copy Markdown
Contributor Author

Added some require tests.

It got a bit odd trying to figure out how to use rootDir and baseUrl correctly.

In getAbsoluteImportPath, baseUrl causes the transpiler to potentially set up an absolute path to the specified module, this can't work for Lua, can't be tested using the current tools and this option doesn't cause this behavior in tsc. tsc just leaves the require path alone even when baseUrl is specified during transpilation.

The behavior of rootDir in getImportPath I think is redundant as the same relative path is calculated or the program leads into the baseUrl behavior which has the issues above.

From what I understand...

rootDir specifies the directory for all the source files.

baseUrl is used to specify a directory with non-relative/globally available definitions, the transpiler doesn't assist in making them available.

Hope this is ok, just trying to keep the behavior of the options the same.

@Perryvw
Copy link
Copy Markdown
Member

Perryvw commented Feb 11, 2019

Thanks for adding the tests. I'm happy with the PR, the only unknown for me now is the behavior of those config options. To clarify: We aim to have these options work the same in tsc and tstl. I'm not entirely sure on their behavior right now, I'll do some testing later today!

.replace(".\\", "")
.replace("./", "")
.replace("/", ".")
.replace("\\", ".");
Copy link
Copy Markdown
Member

@lolleko lolleko Feb 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backslashes can be used in filenames in some POSIX environments and should not be replaced on POSIX.

Ideally filePath should be converted using nodes path lib, maybe just using path.sep (https://nodejs.org/api/path.html#path_path_sep) is enough.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can TypeScript and Lua reference a module on a POSIX system with a backslash in its name?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, never tried it. Nevertheless it would be nicer to use a platform independent solution here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't use path.sep because Windows paths can have either one of the slashes. But I have made it so non-win32 systems do not have their backslashes removed.

private getImportPath(relativePath: string): string {
// Calculate absolute path to import
const absolutePathToImport = this.getAbsoluteImportPath(relativePath);
if (this.options.rootDir) {
Copy link
Copy Markdown
Member

@lolleko lolleko Feb 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree that the rootDir Implementation is a bit weird and needs a rework, along side with baseUrl(s) you should not just remove it.
This will break paths that include files from a parent directory.

For example 2 files src/lib.ts and src/subdir/subdir2/nested.ts
nested.ts:
import * as lib from "../../lib.ts

The above should get converted to require("lib"). Which I think is what the current implementation does via path.resolve and replace.

Probably one of the oldest pieces of code in this project, which could explain why there are no tests for it.

So please also add tests for paths with ...

EDIT:
FYI rootDir is always set: If not specified via CLI or config rootDir is set to the project or working directory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the info, I'll keep this use case working by adding the code back.

My current tests are just matching the literal string in the require path to what you'd expect in a Lua program.

I don't think I can add add tests for .. since to test the workaround functionally there may need to be a testing tool to execute a Lua project involving multiple files at different locations.

I'll add the code back but I can't figure out how to build some test cases for it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Figured out a way to test .. paths, modified Compiler.ts to do it.

private pathToLuaRequirePath(filePath: string): string {
return filePath.replace(/\.json$/, '').replace(new RegExp("\\\\|\/", "g"), ".");
private formatPathToLuaPath(filePath: string): string {
if (process.platform === "win32") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lost during merge:

Suggested change
if (process.platform === "win32") {
filePath = filePath.replace(/\.json$/, '');
if (process.platform === "win32") {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find, adding that back

.replace(/\.\//g, "")
.replace(/\//g, ".");
.replace(/\//g, ".")
.replace(/\.json$/, "");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you do the json replacement fist? Otherwise it would break modules named json, see #418.

.replace(/\\/g, ".");
}
return filePath
.replace(/\.json$/, "")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be before windows part as well. Or, maybe, just make windows part replace backslashes with slashes to make it cleaner?

@Perryvw Perryvw merged commit 9a23ce3 into TypeScriptToLua:master Feb 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants