This commit is contained in:
Jake Bailey 2024-11-05 14:35:02 -08:00 коммит произвёл GitHub
Родитель 82a04b29b4
Коммит 9d7e087022
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 60 добавлений и 100 удалений

Просмотреть файл

@ -604,14 +604,6 @@ export const knip = task({
run: () => exec(process.execPath, ["node_modules/knip/bin/knip.js", "--tags=+internal,-knipignore", "--exclude=duplicates,enumMembers", ...(cmdLineOptions.fix ? ["--fix"] : [])]),
});
const { main: cancellationToken, watch: watchCancellationToken } = entrypointBuildTask({
name: "cancellation-token",
project: "src/cancellationToken",
srcEntrypoint: "./src/cancellationToken/cancellationToken.ts",
builtEntrypoint: "./built/local/cancellationToken/cancellationToken.js",
output: "./built/local/cancellationToken.js",
});
const { main: typingsInstaller, watch: watchTypingsInstaller } = entrypointBuildTask({
name: "typings-installer",
buildDeps: [generateDiagnostics],
@ -661,14 +653,14 @@ const copyBuiltLocalDiagnosticMessages = task({
export const otherOutputs = task({
name: "other-outputs",
description: "Builds miscelaneous scripts and documents distributed with the LKG",
dependencies: [cancellationToken, typingsInstaller, watchGuard, generateTypesMap, copyBuiltLocalDiagnosticMessages],
dependencies: [typingsInstaller, watchGuard, generateTypesMap, copyBuiltLocalDiagnosticMessages],
});
export const watchOtherOutputs = task({
name: "watch-other-outputs",
description: "Builds miscelaneous scripts and documents distributed with the LKG",
hiddenFromTaskList: true,
dependencies: [watchCancellationToken, watchTypingsInstaller, watchWatchGuard, generateTypesMap, copyBuiltLocalDiagnosticMessages],
dependencies: [watchTypingsInstaller, watchWatchGuard, generateTypesMap, copyBuiltLocalDiagnosticMessages],
});
export const local = task({
@ -916,7 +908,6 @@ export const produceLKG = task({
}
const expectedFiles = [
"built/local/cancellationToken.js",
"built/local/tsc.js",
"built/local/_tsc.js",
"built/local/tsserver.js",

Просмотреть файл

@ -3,7 +3,6 @@
"includeEntryExports": true,
"entry": [
"Herebyfile.mjs",
"src/cancellationToken/cancellationToken.ts",
"src/testRunner/_namespaces/Harness.ts",
"src/tsc/tsc.ts",
"src/tsserver/server.ts",

Просмотреть файл

@ -48,7 +48,6 @@ async function copyTypesMap() {
}
async function copyScriptOutputs() {
await copyFromBuiltLocal("cancellationToken.js");
await copyFromBuiltLocal("tsc.js");
await copyFromBuiltLocal("_tsc.js");
await copyFromBuiltLocal("tsserver.js");

Просмотреть файл

@ -1,69 +0,0 @@
import * as fs from "fs";
interface ServerCancellationToken {
isCancellationRequested(): boolean;
setRequest(requestId: number): void;
resetRequest(requestId: number): void;
}
function pipeExists(name: string): boolean {
// Unlike statSync, existsSync doesn't throw an exception if the target doesn't exist.
// A comment in the node code suggests they're stuck with that decision for back compat
// (https://github.com/nodejs/node/blob/9da241b600182a9ff400f6efc24f11a6303c27f7/lib/fs.js#L222).
// Caveat: If a named pipe does exist, the first call to existsSync will return true, as for
// statSync. Subsequent calls will return false, whereas statSync would throw an exception
// indicating that the pipe was busy. The difference is immaterial, since our statSync
// implementation returned false from its catch block.
return fs.existsSync(name);
}
function createCancellationToken(args: string[]): ServerCancellationToken {
let cancellationPipeName: string | undefined;
for (let i = 0; i < args.length - 1; i++) {
if (args[i] === "--cancellationPipeName") {
cancellationPipeName = args[i + 1];
break;
}
}
if (!cancellationPipeName) {
return {
isCancellationRequested: () => false,
setRequest: (_requestId: number): void => void 0,
resetRequest: (_requestId: number): void => void 0,
};
}
// cancellationPipeName is a string without '*' inside that can optionally end with '*'
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
// server will synchronously check the presence of the pipe and treat its existence as indicator that current request should be canceled.
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancellationPipeName.
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
const namePrefix = cancellationPipeName.slice(0, -1);
if (namePrefix.length === 0 || namePrefix.includes("*")) {
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
}
let perRequestPipeName: string | undefined;
let currentRequestId: number;
return {
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
setRequest(requestId: number) {
currentRequestId = requestId;
perRequestPipeName = namePrefix + requestId;
},
resetRequest(requestId: number) {
if (currentRequestId !== requestId) {
throw new Error(`Mismatched request id, expected ${currentRequestId}, actual ${requestId}`);
}
perRequestPipeName = undefined;
},
};
}
else {
return {
isCancellationRequested: () => pipeExists(cancellationPipeName),
setRequest: (_requestId: number): void => void 0,
resetRequest: (_requestId: number): void => void 0,
};
}
}
export = createCancellationToken;

Просмотреть файл

@ -1,9 +0,0 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"types": [
"node"
]
},
"include": ["**/*"]
}

Просмотреть файл

@ -2,7 +2,6 @@
"files": [],
"include": [],
"references": [
{ "path": "./cancellationToken" },
{ "path": "./compiler" },
{ "path": "./deprecatedCompat" },
{ "path": "./harness" },

Просмотреть файл

@ -275,14 +275,7 @@ export function initializeNodeSystem(): StartInput {
sys.gc = () => global.gc?.();
}
let cancellationToken: ts.server.ServerCancellationToken;
try {
const factory = require("./cancellationToken.js");
cancellationToken = factory(sys.args);
}
catch {
cancellationToken = ts.server.nullCancellationToken;
}
const cancellationToken = createCancellationToken(sys.args);
const localeStr = ts.server.findArgument("--locale");
if (localeStr) {
@ -668,3 +661,60 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger
return combinePaths(normalizeSlashes(homePath), cacheFolder);
}
}
function pipeExists(name: string): boolean {
// Unlike statSync, existsSync doesn't throw an exception if the target doesn't exist.
// A comment in the node code suggests they're stuck with that decision for back compat
// (https://github.com/nodejs/node/blob/9da241b600182a9ff400f6efc24f11a6303c27f7/lib/fs.js#L222).
// Caveat: If a named pipe does exist, the first call to existsSync will return true, as for
// statSync. Subsequent calls will return false, whereas statSync would throw an exception
// indicating that the pipe was busy. The difference is immaterial, since our statSync
// implementation returned false from its catch block.
return fs.existsSync(name);
}
function createCancellationToken(args: string[]): ts.server.ServerCancellationToken {
let cancellationPipeName: string | undefined;
for (let i = 0; i < args.length - 1; i++) {
if (args[i] === "--cancellationPipeName") {
cancellationPipeName = args[i + 1];
break;
}
}
if (!cancellationPipeName) {
return ts.server.nullCancellationToken;
}
// cancellationPipeName is a string without '*' inside that can optionally end with '*'
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
// server will synchronously check the presence of the pipe and treat its existence as indicator that current request should be canceled.
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancellationPipeName.
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
const namePrefix = cancellationPipeName.slice(0, -1);
if (namePrefix.length === 0 || namePrefix.includes("*")) {
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
}
let perRequestPipeName: string | undefined;
let currentRequestId: number;
return {
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
setRequest(requestId: number) {
currentRequestId = requestId;
perRequestPipeName = namePrefix + requestId;
},
resetRequest(requestId: number) {
if (currentRequestId !== requestId) {
throw new Error(`Mismatched request id, expected ${currentRequestId}, actual ${requestId}`);
}
perRequestPipeName = undefined;
},
};
}
else {
return {
isCancellationRequested: () => pipeExists(cancellationPipeName),
setRequest: (_requestId: number): void => void 0,
resetRequest: (_requestId: number): void => void 0,
};
}
}