Skip to content

Commit

Permalink
fix: autocomplete supports adding extensions (#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
axetroy authored Aug 28, 2020
1 parent 2cffc07 commit 1326b18
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 12 deletions.
15 changes: 15 additions & 0 deletions core/deno_normalize_import_statement.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,19 @@ test("core / deno_normalize_import_statement", () => {
`import { example } from "https://example.com/foo/bar.ts";`
)
).toEqual(`import { example } from "https://example.com/foo/bar.ts";`);

expect(
normalizeImportStatement(__filename, `import { example } from "./deno";`)
).toEqual(`import { example } from "./deno.ts";`);

expect(
normalizeImportStatement(
__filename,
`import { example } from "./testdata/file_walker/a";`
)
).toEqual(`import { example } from "./testdata/file_walker/a.js";`);

expect(
normalizeImportStatement(__filename, `import { example } from "./none";`)
).toEqual(`import { example } from "./none";`);
});
28 changes: 17 additions & 11 deletions core/deno_normalize_import_statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import * as path from "path";

import { getDenoDepsDir } from "./deno";
import { CacheModule } from "./deno_cache";
import { normalizeFilepath } from "./util";
import { normalizeFilepath, findNonExtensionModule } from "./util";
import { Logger } from "./logger";

/**
* Normalize import statement
* @param importStatement eg. `import { path } from "../../../../Library/Caches/deno/deps/https/example.com/da88efaa8b70cda7903ddc29b8d4c6ea3015de65329ea393289f4104ae2da941"`
* @returns string eg. `https://example.com/demo/sub/mod.ts`
* eg. `import { path } from "../../../../Library/Caches/deno/deps/https/example.com/da88efaa8b70cda7903ddc29b8d4c6ea3015de65329ea393289f4104ae2da941"`
* eg. `import { foo } from "./bar"`
* @param importStatement
* eg. `import { path } from "https://example.com/demo/sub/mod.ts"`
* eg. `import { foo } from "./bar.ts"`
* @returns string
*/
export function normalizeImportStatement(
filename: string,
Expand All @@ -31,26 +35,28 @@ export function normalizeImportStatement(
? moduleFilepath
: path.resolve(path.dirname(filename), moduleFilepath)
);
const rest = matcher[3];
const rest = matcher[3] || "";

/* istanbul ignore next */
logger?.info(
`normalize import \`${importStatement}\` in file \`${filename}\` with module \`${moduleAbsoluteFilepath}\``
);

/* istanbul ignore else */
if (moduleAbsoluteFilepath.startsWith(getDenoDepsDir())) {
const cache = CacheModule.create(moduleAbsoluteFilepath);
/* istanbul ignore else */
if (cache) {
importStatement = `import ${importModuleNames} from "${
cache.meta.url
}"${
/* istanbul ignore next */
rest ? rest : ""
}`;
importStatement = `import ${importModuleNames} from "${cache.meta.url}"${rest}`;
}
}
// if cache not found. then it should be relative path
// eg. `import { foo } from "./bar"`
else if (moduleName.startsWith(".")) {
importStatement = `import ${importModuleNames} from "${findNonExtensionModule(
filename,
moduleName
)}"${rest}`;
}
}

return importStatement;
Expand Down
10 changes: 10 additions & 0 deletions core/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
normalizeFilepath,
isValidDenoDocument,
isUntitledDocument,
findNonExtensionModule,
} from "./util";

test("core / util / pathExists", async () => {
Expand Down Expand Up @@ -72,3 +73,12 @@ test("core / util / isUntitledDocument", () => {
expect(isUntitledDocument("../bar")).toBe(false);
expect(isUntitledDocument("untitled: ")).toBe(true);
});

test("core / util / findNonExtensionModule", () => {
expect(findNonExtensionModule(__filename, "./deno")).toBe("./deno.ts");
expect(findNonExtensionModule(__filename, "./logger")).toBe("./logger.ts");
expect(findNonExtensionModule(__filename, "./testdata/file_walker/a")).toBe(
"./testdata/file_walker/a.js"
);
expect(findNonExtensionModule(__filename, "./none")).toBe("./none");
});
43 changes: 42 additions & 1 deletion core/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { promises as fs, statSync } from "fs";
import crypto from "crypto";
import * as path from "path";
import path from "path";

export function pathExistsSync(filepath: string): boolean {
try {
Expand Down Expand Up @@ -80,3 +80,44 @@ export function isUntitledDocument(filename: string): boolean {
// In vscode, tsserver may crash because a temporary document is not saved
return /^untitled:/.test(filename);
}

/**
* find module which has no extension name
* We hope it can find the module correctly in Deno's way
* eg. `import { foo } from "./bar"` should be `import { foo } from "./bar.ts"`
* @param filepath
* @param moduleName
*/
export function findNonExtensionModule(
filepath: string,
moduleName: string
): string {
function resolveModule(modulePath: string): string | void {
if (pathExistsSync(path.resolve(path.dirname(filepath), modulePath))) {
return modulePath;
}

return;
}

const denoSupportedExtensions = [
".ts",
".tsx",
".d.ts",
".js",
".jsx",
".mjs",
];

while (denoSupportedExtensions.length) {
const extension = denoSupportedExtensions.shift();

const modulePath = resolveModule(moduleName + extension);

if (modulePath) {
return modulePath;
}
}

return moduleName;
}

0 comments on commit 1326b18

Please sign in to comment.