Skip to content

Commit 4d035ba

Browse files
committed
Behave as if package json doesnt exist in case of invalid json in package json
1 parent dfa4bc0 commit 4d035ba

File tree

6 files changed

+93
-55
lines changed

6 files changed

+93
-55
lines changed

src/server/packageJsonCache.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ts.server {
99
}
1010

1111
export function createPackageJsonCache(project: Project): PackageJsonCache {
12-
const packageJsons = createMap<PackageJsonInfo>();
12+
const packageJsons = createMap<PackageJsonInfo | false>();
1313
const directoriesWithoutPackageJson = createMap<true>();
1414
return {
1515
addOrUpdate,
@@ -18,7 +18,7 @@ namespace ts.server {
1818
directoriesWithoutPackageJson.set(getDirectoryPath(fileName), true);
1919
},
2020
getInDirectory: directory => {
21-
return packageJsons.get(combinePaths(directory, "package.json"));
21+
return packageJsons.get(combinePaths(directory, "package.json")) || undefined;
2222
},
2323
directoryHasPackageJson,
2424
searchDirectoryAndAncestors: directory => {
@@ -39,7 +39,7 @@ namespace ts.server {
3939

4040
function addOrUpdate(fileName: Path) {
4141
const packageJsonInfo = createPackageJsonInfo(fileName, project);
42-
if (packageJsonInfo) {
42+
if (packageJsonInfo !== undefined) {
4343
packageJsons.set(fileName, packageJsonInfo);
4444
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
4545
}

src/server/project.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,8 @@ namespace ts.server {
14741474
case Ternary.True:
14751475
const packageJsonFileName = combinePaths(directory, "package.json");
14761476
watchPackageJsonFile(packageJsonFileName);
1477-
result.push(Debug.assertDefined(packageJsonCache.getInDirectory(directory)));
1477+
const info = packageJsonCache.getInDirectory(directory);
1478+
if (info) result.push(info);
14781479
}
14791480
if (rootPath && rootPath === toPath(directory)) {
14801481
return true;

src/services/utilities.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,7 +2210,7 @@ namespace ts {
22102210
return packageJsons;
22112211
}
22122212

2213-
export function createPackageJsonInfo(fileName: string, host: LanguageServiceHost): PackageJsonInfo | undefined {
2213+
export function createPackageJsonInfo(fileName: string, host: LanguageServiceHost): PackageJsonInfo | false | undefined {
22142214
if (!host.readFile) {
22152215
return undefined;
22162216
}
@@ -2221,19 +2221,18 @@ namespace ts {
22212221
if (!stringContent) return undefined;
22222222

22232223
const content = tryParseJson(stringContent) as PackageJsonRaw;
2224+
if (!content) return false;
22242225
const info: Pick<PackageJsonInfo, typeof dependencyKeys[number]> = {};
2225-
if (content) {
2226-
for (const key of dependencyKeys) {
2227-
const dependencies = content[key];
2228-
if (!dependencies) {
2229-
continue;
2230-
}
2231-
const dependencyMap = createMap<string>();
2232-
for (const packageName in dependencies) {
2233-
dependencyMap.set(packageName, dependencies[packageName]);
2234-
}
2235-
info[key] = dependencyMap;
2226+
for (const key of dependencyKeys) {
2227+
const dependencies = content[key];
2228+
if (!dependencies) {
2229+
continue;
2230+
}
2231+
const dependencyMap = createMap<string>();
2232+
for (const packageName in dependencies) {
2233+
dependencyMap.set(packageName, dependencies[packageName]);
22362234
}
2235+
info[key] = dependencyMap;
22372236
}
22382237

22392238
const dependencyGroups = [

src/testRunner/unittests/tsserver/packageJsonInfo.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,19 @@ namespace ts.projectSystem {
7474

7575
it("handles errors in json parsing of package.json", () => {
7676
const packageJsonContent = `{ "mod" }`;
77-
const { project } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]);
77+
const { project, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]);
7878
project.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
7979
const packageJsonInfo = project.packageJsonCache.getInDirectory("/" as Path)!;
80-
assert.isObject(packageJsonInfo);
81-
assert.isUndefined(packageJsonInfo.dependencies);
82-
assert.isUndefined(packageJsonInfo.devDependencies);
83-
assert.isUndefined(packageJsonInfo.peerDependencies);
84-
assert.isUndefined(packageJsonInfo.optionalDependencies);
80+
assert.isUndefined(packageJsonInfo);
81+
82+
host.writeFile(packageJson.path, packageJson.content);
83+
project.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
84+
const packageJsonInfo2 = project.packageJsonCache.getInDirectory("/" as Path)!;
85+
assert.ok(packageJsonInfo2);
86+
assert.ok(packageJsonInfo2.dependencies);
87+
assert.ok(packageJsonInfo2.devDependencies);
88+
assert.ok(packageJsonInfo2.peerDependencies);
89+
assert.ok(packageJsonInfo2.optionalDependencies);
8590
});
8691
});
8792

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
//@noEmit: true
4+
5+
//@Filename: /package.json
6+
////{
7+
//// "mod"
8+
//// "dependencies": {
9+
//// "react": "*"
10+
//// }
11+
////}
12+
13+
//@Filename: /node_modules/react/index.d.ts
14+
////export declare var React: any;
15+
16+
//@Filename: /node_modules/react/package.json
17+
////{
18+
//// "name": "react",
19+
//// "types": "./index.d.ts"
20+
////}
21+
22+
//@Filename: /node_modules/fake-react/index.d.ts
23+
////export declare var ReactFake: any;
24+
25+
//@Filename: /node_modules/fake-react/package.json
26+
////{
27+
//// "name": "fake-react",
28+
//// "types": "./index.d.ts"
29+
////}
30+
31+
//@Filename: /src/index.ts
32+
////const x = Re/**/
33+
34+
verify.completions({
35+
marker: test.marker(""),
36+
isNewIdentifierLocation: true,
37+
includes: [{
38+
name: "React",
39+
hasAction: true,
40+
source: "/node_modules/react/index",
41+
sortText: completion.SortText.AutoImportSuggestions
42+
},
43+
{
44+
name: "ReactFake",
45+
hasAction: true,
46+
source: "/node_modules/fake-react/index",
47+
sortText: completion.SortText.AutoImportSuggestions
48+
}
49+
],
50+
preferences: {
51+
includeCompletionsForModuleExports: true
52+
}
53+
});

tests/cases/fourslash/server/importSuggestionsCache_invalidPackageJson.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,16 @@
2222
////
2323
////readF/**/
2424

25-
verifyExcludes("readFile");
26-
edit.replaceLine(0, "import { promisify } from 'util';");
27-
verifyIncludes("readFile");
28-
edit.deleteLine(0);
29-
verifyExcludes("readFile");
30-
31-
function verifyIncludes(name: string) {
32-
goTo.marker("");
33-
verify.completions({
34-
includes: {
35-
name,
36-
source: "fs",
37-
hasAction: true,
38-
sortText: completion.SortText.AutoImportSuggestions,
39-
},
40-
preferences: {
41-
includeCompletionsForModuleExports: true,
42-
includeInsertTextCompletions: true,
43-
},
44-
});
45-
}
46-
47-
function verifyExcludes(name: string) {
48-
goTo.marker("");
49-
verify.completions({
50-
excludes: name,
51-
preferences: {
52-
includeCompletionsForModuleExports: true,
53-
includeInsertTextCompletions: true,
54-
},
55-
});
56-
}
57-
25+
goTo.marker("");
26+
verify.completions({
27+
includes: {
28+
name: "readFile",
29+
source: "fs",
30+
hasAction: true,
31+
sortText: completion.SortText.AutoImportSuggestions,
32+
},
33+
preferences: {
34+
includeCompletionsForModuleExports: true,
35+
includeInsertTextCompletions: true,
36+
},
37+
});

0 commit comments

Comments
 (0)