Skip to content

Commit 264d27e

Browse files
TypeScript Botandrewbranchtypescript-bot
authored
🤖 Pick PR microsoft#39937 (Handle empty package.json files) into release-4.0 (microsoft#39938)
* Cherry-pick PR microsoft#39937 into release-4.0 Component commits: 0b9b321 Handle empty package.json files * Update LKG Co-authored-by: Andrew Branch <[email protected]> Co-authored-by: typescript-bot <[email protected]>
1 parent 071b649 commit 264d27e

File tree

10 files changed

+66
-54
lines changed

10 files changed

+66
-54
lines changed

‎lib/tsc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20154,11 +20154,13 @@ var ts;
2015420154
};
2015520155
ts.classPrivateFieldGetHelper = {
2015620156
name: "typescript:classPrivateFieldGet",
20157+
importName: "__classPrivateFieldGet",
2015720158
scoped: false,
2015820159
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2015920160
};
2016020161
ts.classPrivateFieldSetHelper = {
2016120162
name: "typescript:classPrivateFieldSet",
20163+
importName: "__classPrivateFieldSet",
2016220164
scoped: false,
2016320165
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2016420166
};

‎lib/tsserver.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25223,11 +25223,13 @@ var ts;
2522325223
// Class fields helpers
2522425224
ts.classPrivateFieldGetHelper = {
2522525225
name: "typescript:classPrivateFieldGet",
25226+
importName: "__classPrivateFieldGet",
2522625227
scoped: false,
2522725228
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2522825229
};
2522925230
ts.classPrivateFieldSetHelper = {
2523025231
name: "typescript:classPrivateFieldSet",
25232+
importName: "__classPrivateFieldSet",
2523125233
scoped: false,
2523225234
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2523325235
};
@@ -113237,9 +113239,7 @@ var ts;
113237113239
return undefined;
113238113240
}
113239113241
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
113240-
var stringContent = host.readFile(fileName);
113241-
if (!stringContent)
113242-
return undefined;
113242+
var stringContent = host.readFile(fileName) || "";
113243113243
var content = tryParseJson(stringContent);
113244113244
var info = {};
113245113245
if (content) {
@@ -152444,13 +152444,12 @@ var ts;
152444152444
};
152445152445
/*@internal*/
152446152446
ProjectService.prototype.getPackageJsonsVisibleToFile = function (fileName, rootDir) {
152447+
var _this = this;
152447152448
var packageJsonCache = this.packageJsonCache;
152448-
var watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
152449-
var toPath = this.toPath.bind(this);
152450-
var rootPath = rootDir && toPath(rootDir);
152451-
var filePath = toPath(fileName);
152449+
var rootPath = rootDir && this.toPath(rootDir);
152450+
var filePath = this.toPath(fileName);
152452152451
var result = [];
152453-
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), function processDirectory(directory) {
152452+
var processDirectory = function (directory) {
152454152453
switch (packageJsonCache.directoryHasPackageJson(directory)) {
152455152454
// Sync and check same directory again
152456152455
case 1 /* Maybe */:
@@ -152459,15 +152458,16 @@ var ts;
152459152458
// Check package.json
152460152459
case -1 /* True */:
152461152460
var packageJsonFileName = ts.combinePaths(directory, "package.json");
152462-
watchPackageJsonFile(packageJsonFileName);
152461+
_this.watchPackageJsonFile(packageJsonFileName);
152463152462
var info = packageJsonCache.getInDirectory(directory);
152464152463
if (info)
152465152464
result.push(info);
152466152465
}
152467-
if (rootPath && rootPath === toPath(directory)) {
152466+
if (rootPath && rootPath === _this.toPath(directory)) {
152468152467
return true;
152469152468
}
152470-
});
152469+
};
152470+
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), processDirectory);
152471152471
return result;
152472152472
};
152473152473
/*@internal*/
@@ -152572,11 +152572,9 @@ var ts;
152572152572
},
152573152573
};
152574152574
function addOrUpdate(fileName) {
152575-
var packageJsonInfo = ts.createPackageJsonInfo(fileName, host.host);
152576-
if (packageJsonInfo !== undefined) {
152577-
packageJsons.set(fileName, packageJsonInfo);
152578-
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
152579-
}
152575+
var packageJsonInfo = ts.Debug.checkDefined(ts.createPackageJsonInfo(fileName, host.host));
152576+
packageJsons.set(fileName, packageJsonInfo);
152577+
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
152580152578
}
152581152579
function directoryHasPackageJson(directory) {
152582152580
return packageJsons.has(ts.combinePaths(directory, "package.json")) ? -1 /* True */ :

‎lib/tsserverlibrary.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25417,11 +25417,13 @@ var ts;
2541725417
// Class fields helpers
2541825418
ts.classPrivateFieldGetHelper = {
2541925419
name: "typescript:classPrivateFieldGet",
25420+
importName: "__classPrivateFieldGet",
2542025421
scoped: false,
2542125422
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2542225423
};
2542325424
ts.classPrivateFieldSetHelper = {
2542425425
name: "typescript:classPrivateFieldSet",
25426+
importName: "__classPrivateFieldSet",
2542525427
scoped: false,
2542625428
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2542725429
};
@@ -113804,9 +113806,7 @@ var ts;
113804113806
return undefined;
113805113807
}
113806113808
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
113807-
var stringContent = host.readFile(fileName);
113808-
if (!stringContent)
113809-
return undefined;
113809+
var stringContent = host.readFile(fileName) || "";
113810113810
var content = tryParseJson(stringContent);
113811113811
var info = {};
113812113812
if (content) {
@@ -152638,13 +152638,12 @@ var ts;
152638152638
};
152639152639
/*@internal*/
152640152640
ProjectService.prototype.getPackageJsonsVisibleToFile = function (fileName, rootDir) {
152641+
var _this = this;
152641152642
var packageJsonCache = this.packageJsonCache;
152642-
var watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
152643-
var toPath = this.toPath.bind(this);
152644-
var rootPath = rootDir && toPath(rootDir);
152645-
var filePath = toPath(fileName);
152643+
var rootPath = rootDir && this.toPath(rootDir);
152644+
var filePath = this.toPath(fileName);
152646152645
var result = [];
152647-
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), function processDirectory(directory) {
152646+
var processDirectory = function (directory) {
152648152647
switch (packageJsonCache.directoryHasPackageJson(directory)) {
152649152648
// Sync and check same directory again
152650152649
case 1 /* Maybe */:
@@ -152653,15 +152652,16 @@ var ts;
152653152652
// Check package.json
152654152653
case -1 /* True */:
152655152654
var packageJsonFileName = ts.combinePaths(directory, "package.json");
152656-
watchPackageJsonFile(packageJsonFileName);
152655+
_this.watchPackageJsonFile(packageJsonFileName);
152657152656
var info = packageJsonCache.getInDirectory(directory);
152658152657
if (info)
152659152658
result.push(info);
152660152659
}
152661-
if (rootPath && rootPath === toPath(directory)) {
152660+
if (rootPath && rootPath === _this.toPath(directory)) {
152662152661
return true;
152663152662
}
152664-
});
152663+
};
152664+
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), processDirectory);
152665152665
return result;
152666152666
};
152667152667
/*@internal*/
@@ -152766,11 +152766,9 @@ var ts;
152766152766
},
152767152767
};
152768152768
function addOrUpdate(fileName) {
152769-
var packageJsonInfo = ts.createPackageJsonInfo(fileName, host.host);
152770-
if (packageJsonInfo !== undefined) {
152771-
packageJsons.set(fileName, packageJsonInfo);
152772-
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
152773-
}
152769+
var packageJsonInfo = ts.Debug.checkDefined(ts.createPackageJsonInfo(fileName, host.host));
152770+
packageJsons.set(fileName, packageJsonInfo);
152771+
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
152774152772
}
152775152773
function directoryHasPackageJson(directory) {
152776152774
return packageJsons.has(ts.combinePaths(directory, "package.json")) ? -1 /* True */ :

‎lib/typescript.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25417,11 +25417,13 @@ var ts;
2541725417
// Class fields helpers
2541825418
ts.classPrivateFieldGetHelper = {
2541925419
name: "typescript:classPrivateFieldGet",
25420+
importName: "__classPrivateFieldGet",
2542025421
scoped: false,
2542125422
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2542225423
};
2542325424
ts.classPrivateFieldSetHelper = {
2542425425
name: "typescript:classPrivateFieldSet",
25426+
importName: "__classPrivateFieldSet",
2542525427
scoped: false,
2542625428
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2542725429
};
@@ -113804,9 +113806,7 @@ var ts;
113804113806
return undefined;
113805113807
}
113806113808
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
113807-
var stringContent = host.readFile(fileName);
113808-
if (!stringContent)
113809-
return undefined;
113809+
var stringContent = host.readFile(fileName) || "";
113810113810
var content = tryParseJson(stringContent);
113811113811
var info = {};
113812113812
if (content) {

‎lib/typescriptServices.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25417,11 +25417,13 @@ var ts;
2541725417
// Class fields helpers
2541825418
ts.classPrivateFieldGetHelper = {
2541925419
name: "typescript:classPrivateFieldGet",
25420+
importName: "__classPrivateFieldGet",
2542025421
scoped: false,
2542125422
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2542225423
};
2542325424
ts.classPrivateFieldSetHelper = {
2542425425
name: "typescript:classPrivateFieldSet",
25426+
importName: "__classPrivateFieldSet",
2542525427
scoped: false,
2542625428
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2542725429
};
@@ -113804,9 +113806,7 @@ var ts;
113804113806
return undefined;
113805113807
}
113806113808
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
113807-
var stringContent = host.readFile(fileName);
113808-
if (!stringContent)
113809-
return undefined;
113809+
var stringContent = host.readFile(fileName) || "";
113810113810
var content = tryParseJson(stringContent);
113811113811
var info = {};
113812113812
if (content) {

‎lib/typingsInstaller.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25212,11 +25212,13 @@ var ts;
2521225212
// Class fields helpers
2521325213
ts.classPrivateFieldGetHelper = {
2521425214
name: "typescript:classPrivateFieldGet",
25215+
importName: "__classPrivateFieldGet",
2521525216
scoped: false,
2521625217
text: "\n var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to get private field on non-instance\");\n }\n return privateMap.get(receiver);\n };"
2521725218
};
2521825219
ts.classPrivateFieldSetHelper = {
2521925220
name: "typescript:classPrivateFieldSet",
25221+
importName: "__classPrivateFieldSet",
2522025222
scoped: false,
2522125223
text: "\n var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError(\"attempted to set private field on non-instance\");\n }\n privateMap.set(receiver, value);\n return value;\n };"
2522225224
};

‎src/server/editorServices.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,12 +3774,10 @@ namespace ts.server {
37743774
/*@internal*/
37753775
getPackageJsonsVisibleToFile(fileName: string, rootDir?: string): readonly PackageJsonInfo[] {
37763776
const packageJsonCache = this.packageJsonCache;
3777-
const watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
3778-
const toPath = this.toPath.bind(this);
3779-
const rootPath = rootDir && toPath(rootDir);
3780-
const filePath = toPath(fileName);
3777+
const rootPath = rootDir && this.toPath(rootDir);
3778+
const filePath = this.toPath(fileName);
37813779
const result: PackageJsonInfo[] = [];
3782-
forEachAncestorDirectory(getDirectoryPath(filePath), function processDirectory(directory): boolean | undefined {
3780+
const processDirectory = (directory: Path): boolean | undefined => {
37833781
switch (packageJsonCache.directoryHasPackageJson(directory)) {
37843782
// Sync and check same directory again
37853783
case Ternary.Maybe:
@@ -3788,15 +3786,16 @@ namespace ts.server {
37883786
// Check package.json
37893787
case Ternary.True:
37903788
const packageJsonFileName = combinePaths(directory, "package.json");
3791-
watchPackageJsonFile(packageJsonFileName);
3789+
this.watchPackageJsonFile(packageJsonFileName as Path);
37923790
const info = packageJsonCache.getInDirectory(directory);
37933791
if (info) result.push(info);
37943792
}
3795-
if (rootPath && rootPath === toPath(directory)) {
3793+
if (rootPath && rootPath === this.toPath(directory)) {
37963794
return true;
37973795
}
3798-
});
3796+
};
37993797

3798+
forEachAncestorDirectory(getDirectoryPath(filePath), processDirectory);
38003799
return result;
38013800
}
38023801

‎src/server/packageJsonCache.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ namespace ts.server {
4242
};
4343

4444
function addOrUpdate(fileName: Path) {
45-
const packageJsonInfo = createPackageJsonInfo(fileName, host.host);
46-
if (packageJsonInfo !== undefined) {
47-
packageJsons.set(fileName, packageJsonInfo);
48-
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
49-
}
45+
const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host));
46+
packageJsons.set(fileName, packageJsonInfo);
47+
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
5048
}
5149

5250
function directoryHasPackageJson(directory: Path) {

‎src/services/utilities.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,9 +2735,7 @@ namespace ts {
27352735

27362736
type PackageJsonRaw = Record<typeof dependencyKeys[number], Record<string, string> | undefined>;
27372737
const dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"] as const;
2738-
const stringContent = host.readFile(fileName);
2739-
if (!stringContent) return undefined;
2740-
2738+
const stringContent = host.readFile(fileName) || "";
27412739
const content = tryParseJson(stringContent) as PackageJsonRaw | undefined;
27422740
const info: Pick<PackageJsonInfo, typeof dependencyKeys[number]> = {};
27432741
if (content) {

‎src/testRunner/unittests/tsserver/packageJsonInfo.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,23 @@ namespace ts.projectSystem {
8282
assert.ok(packageJsonInfo2.peerDependencies);
8383
assert.ok(packageJsonInfo2.optionalDependencies);
8484
});
85+
86+
it("handles empty package.json", () => {
87+
const packageJsonContent = "";
88+
const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]);
89+
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
90+
const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!;
91+
assert.isFalse(packageJsonInfo.parseable);
92+
93+
host.writeFile(packageJson.path, packageJson.content);
94+
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
95+
const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!;
96+
assert.ok(packageJsonInfo2);
97+
assert.ok(packageJsonInfo2.dependencies);
98+
assert.ok(packageJsonInfo2.devDependencies);
99+
assert.ok(packageJsonInfo2.peerDependencies);
100+
assert.ok(packageJsonInfo2.optionalDependencies);
101+
});
85102
});
86103

87104
function setup(files: readonly File[] = [tsConfig, packageJson]) {

0 commit comments

Comments
 (0)