🤖 Pick PR #39937 (Handle empty package.json files) into release-4.0 (#39938)

* Cherry-pick PR #39937 into release-4.0

Component commits:
0b9b321b0c Handle empty package.json files

* Update LKG

Co-authored-by: Andrew Branch <andrew@wheream.io>
Co-authored-by: typescript-bot <typescript@microsoft.com>
This commit is contained in:
TypeScript Bot
2020-08-06 10:37:28 -07:00
committed by GitHub
co-authored by Andrew Branch typescript-bot
parent 071b649d59
commit 264d27e779
10 changed files with 66 additions and 54 deletions
+2
View File
@@ -20154,11 +20154,13 @@ var ts;
};
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
+14 -16
View File
@@ -25223,11 +25223,13 @@ var ts;
// Class fields helpers
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
@@ -113237,9 +113239,7 @@ var ts;
return undefined;
}
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
var stringContent = host.readFile(fileName);
if (!stringContent)
return undefined;
var stringContent = host.readFile(fileName) || "";
var content = tryParseJson(stringContent);
var info = {};
if (content) {
@@ -152444,13 +152444,12 @@ var ts;
};
/*@internal*/
ProjectService.prototype.getPackageJsonsVisibleToFile = function (fileName, rootDir) {
var _this = this;
var packageJsonCache = this.packageJsonCache;
var watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
var toPath = this.toPath.bind(this);
var rootPath = rootDir && toPath(rootDir);
var filePath = toPath(fileName);
var rootPath = rootDir && this.toPath(rootDir);
var filePath = this.toPath(fileName);
var result = [];
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), function processDirectory(directory) {
var processDirectory = function (directory) {
switch (packageJsonCache.directoryHasPackageJson(directory)) {
// Sync and check same directory again
case 1 /* Maybe */:
@@ -152459,15 +152458,16 @@ var ts;
// Check package.json
case -1 /* True */:
var packageJsonFileName = ts.combinePaths(directory, "package.json");
watchPackageJsonFile(packageJsonFileName);
_this.watchPackageJsonFile(packageJsonFileName);
var info = packageJsonCache.getInDirectory(directory);
if (info)
result.push(info);
}
if (rootPath && rootPath === toPath(directory)) {
if (rootPath && rootPath === _this.toPath(directory)) {
return true;
}
});
};
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), processDirectory);
return result;
};
/*@internal*/
@@ -152572,11 +152572,9 @@ var ts;
},
};
function addOrUpdate(fileName) {
var packageJsonInfo = ts.createPackageJsonInfo(fileName, host.host);
if (packageJsonInfo !== undefined) {
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
}
var packageJsonInfo = ts.Debug.checkDefined(ts.createPackageJsonInfo(fileName, host.host));
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
}
function directoryHasPackageJson(directory) {
return packageJsons.has(ts.combinePaths(directory, "package.json")) ? -1 /* True */ :
+14 -16
View File
@@ -25417,11 +25417,13 @@ var ts;
// Class fields helpers
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
@@ -113804,9 +113806,7 @@ var ts;
return undefined;
}
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
var stringContent = host.readFile(fileName);
if (!stringContent)
return undefined;
var stringContent = host.readFile(fileName) || "";
var content = tryParseJson(stringContent);
var info = {};
if (content) {
@@ -152638,13 +152638,12 @@ var ts;
};
/*@internal*/
ProjectService.prototype.getPackageJsonsVisibleToFile = function (fileName, rootDir) {
var _this = this;
var packageJsonCache = this.packageJsonCache;
var watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
var toPath = this.toPath.bind(this);
var rootPath = rootDir && toPath(rootDir);
var filePath = toPath(fileName);
var rootPath = rootDir && this.toPath(rootDir);
var filePath = this.toPath(fileName);
var result = [];
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), function processDirectory(directory) {
var processDirectory = function (directory) {
switch (packageJsonCache.directoryHasPackageJson(directory)) {
// Sync and check same directory again
case 1 /* Maybe */:
@@ -152653,15 +152652,16 @@ var ts;
// Check package.json
case -1 /* True */:
var packageJsonFileName = ts.combinePaths(directory, "package.json");
watchPackageJsonFile(packageJsonFileName);
_this.watchPackageJsonFile(packageJsonFileName);
var info = packageJsonCache.getInDirectory(directory);
if (info)
result.push(info);
}
if (rootPath && rootPath === toPath(directory)) {
if (rootPath && rootPath === _this.toPath(directory)) {
return true;
}
});
};
ts.forEachAncestorDirectory(ts.getDirectoryPath(filePath), processDirectory);
return result;
};
/*@internal*/
@@ -152766,11 +152766,9 @@ var ts;
},
};
function addOrUpdate(fileName) {
var packageJsonInfo = ts.createPackageJsonInfo(fileName, host.host);
if (packageJsonInfo !== undefined) {
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
}
var packageJsonInfo = ts.Debug.checkDefined(ts.createPackageJsonInfo(fileName, host.host));
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(ts.getDirectoryPath(fileName));
}
function directoryHasPackageJson(directory) {
return packageJsons.has(ts.combinePaths(directory, "package.json")) ? -1 /* True */ :
+3 -3
View File
@@ -25417,11 +25417,13 @@ var ts;
// Class fields helpers
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
@@ -113804,9 +113806,7 @@ var ts;
return undefined;
}
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
var stringContent = host.readFile(fileName);
if (!stringContent)
return undefined;
var stringContent = host.readFile(fileName) || "";
var content = tryParseJson(stringContent);
var info = {};
if (content) {
+3 -3
View File
@@ -25417,11 +25417,13 @@ var ts;
// Class fields helpers
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
@@ -113804,9 +113806,7 @@ var ts;
return undefined;
}
var dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
var stringContent = host.readFile(fileName);
if (!stringContent)
return undefined;
var stringContent = host.readFile(fileName) || "";
var content = tryParseJson(stringContent);
var info = {};
if (content) {
+2
View File
@@ -25212,11 +25212,13 @@ var ts;
// Class fields helpers
ts.classPrivateFieldGetHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
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 };"
};
ts.classPrivateFieldSetHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
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 };"
};
+7 -8
View File
@@ -3774,12 +3774,10 @@ namespace ts.server {
/*@internal*/
getPackageJsonsVisibleToFile(fileName: string, rootDir?: string): readonly PackageJsonInfo[] {
const packageJsonCache = this.packageJsonCache;
const watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
const toPath = this.toPath.bind(this);
const rootPath = rootDir && toPath(rootDir);
const filePath = toPath(fileName);
const rootPath = rootDir && this.toPath(rootDir);
const filePath = this.toPath(fileName);
const result: PackageJsonInfo[] = [];
forEachAncestorDirectory(getDirectoryPath(filePath), function processDirectory(directory): boolean | undefined {
const processDirectory = (directory: Path): boolean | undefined => {
switch (packageJsonCache.directoryHasPackageJson(directory)) {
// Sync and check same directory again
case Ternary.Maybe:
@@ -3788,15 +3786,16 @@ namespace ts.server {
// Check package.json
case Ternary.True:
const packageJsonFileName = combinePaths(directory, "package.json");
watchPackageJsonFile(packageJsonFileName);
this.watchPackageJsonFile(packageJsonFileName as Path);
const info = packageJsonCache.getInDirectory(directory);
if (info) result.push(info);
}
if (rootPath && rootPath === toPath(directory)) {
if (rootPath && rootPath === this.toPath(directory)) {
return true;
}
});
};
forEachAncestorDirectory(getDirectoryPath(filePath), processDirectory);
return result;
}
+3 -5
View File
@@ -42,11 +42,9 @@ namespace ts.server {
};
function addOrUpdate(fileName: Path) {
const packageJsonInfo = createPackageJsonInfo(fileName, host.host);
if (packageJsonInfo !== undefined) {
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
}
const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host));
packageJsons.set(fileName, packageJsonInfo);
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
}
function directoryHasPackageJson(directory: Path) {
+1 -3
View File
@@ -2735,9 +2735,7 @@ namespace ts {
type PackageJsonRaw = Record<typeof dependencyKeys[number], Record<string, string> | undefined>;
const dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"] as const;
const stringContent = host.readFile(fileName);
if (!stringContent) return undefined;
const stringContent = host.readFile(fileName) || "";
const content = tryParseJson(stringContent) as PackageJsonRaw | undefined;
const info: Pick<PackageJsonInfo, typeof dependencyKeys[number]> = {};
if (content) {
@@ -82,6 +82,23 @@ namespace ts.projectSystem {
assert.ok(packageJsonInfo2.peerDependencies);
assert.ok(packageJsonInfo2.optionalDependencies);
});
it("handles empty package.json", () => {
const packageJsonContent = "";
const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]);
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!;
assert.isFalse(packageJsonInfo.parseable);
host.writeFile(packageJson.path, packageJson.content);
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!;
assert.ok(packageJsonInfo2);
assert.ok(packageJsonInfo2.dependencies);
assert.ok(packageJsonInfo2.devDependencies);
assert.ok(packageJsonInfo2.peerDependencies);
assert.ok(packageJsonInfo2.optionalDependencies);
});
});
function setup(files: readonly File[] = [tsConfig, packageJson]) {