Skip to content

Bugs in missing import codefix#17302

Merged
minestarks merged 3 commits into
microsoft:masterfrom
minestarks:removeimportfix
Jul 21, 2017
Merged

Bugs in missing import codefix#17302
minestarks merged 3 commits into
microsoft:masterfrom
minestarks:removeimportfix

Conversation

@minestarks
Copy link
Copy Markdown
Member

  • We didn't locate the package.json correctly in cases where the module to be imported is in a subdirectory of the package
  • We didn't look at the types element in package.json (just typings)
  • We didn't remove /index.js from the path if the main module was in a subdirectory

Fixes #16963

- We didn't locate the package.json correctly in cases where the module to be imported is in a subdirectory of the package
- We didn't look at the types element in package.json (just typings)
- We didn't remove /index.js from the path if the main module was in a subdirectory

Fixes microsoft#16963
Comment thread src/services/codefixes/importFixes.ts Outdated
function getNodeResolvablePath(path: string): string {
const fullPathUptoNodeModules = moduleFileName.substring(0, indexOfTopNodeModules - 1);
if (sourceDirectory.indexOf(fullPathUptoNodeModules) === 0) {
const indexOfTopPackageName = indexOfTopNodeModules + 13 /* "node_modules\".length */;
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.

What's the backslash for?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If I change it to a forward slash it may become clearer.
It's trying to say that the constant 13 corresponds to the length of node_modules/, i.e.
"node_modules/".length

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.

Oh, it's a path separator? Forward slash might be more consistent with the code.

Comment thread src/services/codefixes/importFixes.ts Outdated
catch (e) { }

// If the file is index.js, it can be imported by its directory name
if (endsWith(fullModulePathWithoutExtension, "/index")) {
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.

Has the path already been normalized? If not, do you need to check for backslash as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I should check on this. Since /index was existing code, I relied on the assumption that it was normalized -- but wouldn't hurt to verify.

Comment thread src/services/codefixes/importFixes.ts Outdated

const indexOfNodeModules = moduleFileName.indexOf("node_modules");
if (indexOfNodeModules < 0) {
const indexOfTopNodeModules = moduleFileName.indexOf("node_modules");
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.

Seems like this could produce false positives (e.g. "node_modules2").

Copy link
Copy Markdown
Member

@amcasey amcasey Jul 19, 2017

Choose a reason for hiding this comment

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

Would implementing a path splitter simplify the logic in this function?

Comment thread src/services/codefixes/importFixes.ts Outdated
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
if (mainFileRelative) {
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
if (removeFileExtension(mainExportFile) === removeFileExtension(moduleFileName)) {
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.

Does this mean they're allowed to have different file extensions? Also, does case matter?

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.

Also, use fullModulePathWithoutExtension?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Alright, I had to come up with a really contrived case to check the answers to these. Found that a) case doesn't matter but file extensions do. Will update the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Or rather, case sensitivity is based on the file system's case sensitivity

Copy link
Copy Markdown
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

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

LGTM

Comment thread src/services/codefixes/importFixes.ts Outdated
// Example of expected pattern: /base/path/node_modules/[otherpackage/node_modules/]package/[subdirectory/]file.js
// Returns indices: ^ ^ ^ ^

let nodeModulesIndex = 0;
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.

This is the first such index?

Comment thread src/services/codefixes/importFixes.ts Outdated
let packageRootIndex = 0;
let fileNameIndex = 0;

enum States {
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.

const enum?

Comment thread src/services/codefixes/importFixes.ts Outdated
while (partEnd >= 0) {
partStart = partEnd;
partEnd = fullPath.indexOf("/", partStart + 1);
const part = fullPath.substring(partStart, partEnd);
Copy link
Copy Markdown
Member

@amcasey amcasey Jul 20, 2017

Choose a reason for hiding this comment

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

If the goal of doing everything with indices was to avoid creating temporary strings, this should probably be created on demand (e.g. never in States.NodeModules) or, better still, "/node_modules" could be detected in-place.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure.

@minestarks minestarks merged commit 441daa4 into microsoft:master Jul 21, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants