Skip to content

Commit

Permalink
Fix completions when the ts installation and project are on two diffe…
Browse files Browse the repository at this point in the history
…rent windows drive (#35733)

* Fix completions when the ts installation and project are on two different windows drive
Fixes #35512

* Fix typo
  • Loading branch information
sheetalkamat authored Dec 17, 2019
1 parent c73af61 commit f90cde4
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 4 deletions.
13 changes: 10 additions & 3 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ namespace ts.moduleSpecifiers {
return match ? match.length : 0;
}

function comparePathsByNumberOfDirectrorySeparators(a: string, b: string) {
function comparePathsByNumberOfDirectorySeparators(a: string, b: string) {
return compareValues(
numberOfDirectorySeparators(a),
numberOfDirectorySeparators(b)
Expand Down Expand Up @@ -216,7 +216,6 @@ namespace ts.moduleSpecifiers {
for (
let directory = getDirectoryPath(toPath(importingFileName, cwd, getCanonicalFileName));
allFileNames.size !== 0;
directory = getDirectoryPath(directory)
) {
const directoryStart = ensureTrailingDirectorySeparator(directory);
let pathsInDirectory: string[] | undefined;
Expand All @@ -228,10 +227,18 @@ namespace ts.moduleSpecifiers {
});
if (pathsInDirectory) {
if (pathsInDirectory.length > 1) {
pathsInDirectory.sort(comparePathsByNumberOfDirectrorySeparators);
pathsInDirectory.sort(comparePathsByNumberOfDirectorySeparators);
}
sortedPaths.push(...pathsInDirectory);
}
const newDirectory = getDirectoryPath(directory);
if (newDirectory === directory) break;
directory = newDirectory;
}
if (allFileNames.size) {
const remainingPaths = arrayFrom(allFileNames.values());
if (remainingPaths.length > 1) remainingPaths.sort(comparePathsByNumberOfDirectorySeparators);
sortedPaths.push(...remainingPaths);
}
return sortedPaths;
}
Expand Down
2 changes: 1 addition & 1 deletion src/harness/virtualFileSystemWithWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ interface Array<T> { length: number; [n: number]: T; }`
}
else {
// root folder
Debug.assert(this.fs.size === 0);
Debug.assert(this.fs.size === 0 || !!this.windowsStyleRoot);
this.fs.set(path, folder);
}
}
Expand Down
128 changes: 128 additions & 0 deletions src/testRunner/unittests/tsserver/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,133 @@ namespace ts.projectSystem {
}
]);
});

it("works when files are included from two different drives of windows", () => {
const projectRoot = "e:/myproject";
const appPackage: File = {
path: `${projectRoot}/package.json`,
content: JSON.stringify({
name: "test",
version: "0.1.0",
dependencies: {
"react": "^16.12.0",
"react-router-dom": "^5.1.2",
}
})
};
const appFile: File = {
path: `${projectRoot}/src/app.js`,
content: `import React from 'react';
import {
BrowserRouter as Router,
} from "react-router-dom";
`
};
const localNodeModules = `${projectRoot}/node_modules`;
const localAtTypes = `${localNodeModules}/@types`;
const localReactPackage: File = {
path: `${localAtTypes}/react/package.json`,
content: JSON.stringify({
name: "@types/react",
version: "16.9.14",
})
};
const localReact: File = {
path: `${localAtTypes}/react/index.d.ts`,
content: `import * as PropTypes from 'prop-types';
`
};
const localReactRouterDomPackage: File = {
path: `${localNodeModules}/react-router-dom/package.json`,
content: JSON.stringify({
name: "react-router-dom",
version: "5.1.2",
})
};
const localReactRouterDom: File = {
path: `${localNodeModules}/react-router-dom/index.js`,
content: `export function foo() {}`
};
const localPropTypesPackage: File = {
path: `${localAtTypes}/prop-types/package.json`,
content: JSON.stringify({
name: "@types/prop-types",
version: "15.7.3",
})
};
const localPropTypes: File = {
path: `${localAtTypes}/prop-types/index.d.ts`,
content: `export type ReactComponentLike =
| string
| ((props: any, context?: any) => any)
| (new (props: any, context?: any) => any);
`
};

const globalCacheLocation = `c:/typescript`;
const globalAtTypes = `${globalCacheLocation}/node_modules/@types`;
const globalReactRouterDomPackage: File = {
path: `${globalAtTypes}/react-router-dom/package.json`,
content: JSON.stringify({
name: "@types/react-router-dom",
version: "5.1.2",
})
};
const globalReactRouterDom: File = {
path: `${globalAtTypes}/react-router-dom/index.d.ts`,
content: `import * as React from 'react';
export interface BrowserRouterProps {
basename?: string;
getUserConfirmation?: ((message: string, callback: (ok: boolean) => void) => void);
forceRefresh?: boolean;
keyLength?: number;
}`
};
const globalReactPackage: File = {
path: `${globalAtTypes}/react/package.json`,
content: localReactPackage.content
};
const globalReact: File = {
path: `${globalAtTypes}/react/index.d.ts`,
content: localReact.content
};

const filesInProject = [
appFile,
localReact,
localPropTypes,
globalReactRouterDom,
globalReact,
];
const files = [
...filesInProject,
appPackage, libFile,
localReactPackage,
localReactRouterDomPackage, localReactRouterDom,
localPropTypesPackage,
globalReactRouterDomPackage,
globalReactPackage,
];

const host = createServerHost(files, { windowsStyleRoot: "c:/" });
const session = createSession(host, {
typingsInstaller: new TestTypingsInstaller(globalCacheLocation, /*throttleLimit*/ 5, host),
});
const service = session.getProjectService();
openFilesForSession([appFile], session);
checkNumberOfProjects(service, { inferredProjects: 1 });
const windowsStyleLibFilePath = "c:/" + libFile.path.substring(1);
checkProjectActualFiles(service.inferredProjects[0], filesInProject.map(f => f.path).concat(windowsStyleLibFilePath));
session.executeCommandSeq<protocol.CompletionsRequest>({
command: protocol.CommandTypes.CompletionInfo,
arguments: {
file: appFile.path,
line: 5,
offset: 1,
includeExternalModuleExports: true,
includeInsertTextCompletions: true
}
});
});
});
}

0 comments on commit f90cde4

Please sign in to comment.