mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-27 13:42:16 -05:00
add cancellation support
This commit is contained in:
11
Jakefile.js
11
Jakefile.js
@@ -110,6 +110,12 @@ var serverCoreSources = [
|
||||
return path.join(serverDirectory, f);
|
||||
});
|
||||
|
||||
var cancellationTokenSources = [
|
||||
"cancellationToken.ts"
|
||||
].map(function (f) {
|
||||
return path.join(serverDirectory, f);
|
||||
});
|
||||
|
||||
var serverSources = serverCoreSources.concat(servicesSources);
|
||||
|
||||
var languageServiceLibrarySources = [
|
||||
@@ -517,8 +523,11 @@ compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].conca
|
||||
});
|
||||
|
||||
|
||||
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
|
||||
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
|
||||
|
||||
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true);
|
||||
compileFile(serverFile, serverSources,[builtLocalDirectory, copyright, cancellationTokenFile].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true);
|
||||
|
||||
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
|
||||
34
src/server/cancellationToken.ts
Normal file
34
src/server/cancellationToken.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/// <reference path="node.d.ts"/>
|
||||
|
||||
|
||||
// TODO: extract services types
|
||||
interface HostCancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
}
|
||||
|
||||
const fs: typeof NodeJS.fs = require("fs");
|
||||
|
||||
function createCancellationToken(args: string[]): HostCancellationToken {
|
||||
let cancellationPipeName: string;
|
||||
for (let i = 0; i < args.length - 1; i++) {
|
||||
if (args[i] === "--cancellationPipeName") {
|
||||
cancellationPipeName = args[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cancellationPipeName) {
|
||||
return { isCancellationRequested: () => false };
|
||||
}
|
||||
return {
|
||||
isCancellationRequested() {
|
||||
try {
|
||||
fs.statSync(cancellationPipeName);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export = createCancellationToken
|
||||
@@ -129,7 +129,7 @@ namespace ts.server {
|
||||
private resolvedTypeReferenceDirectives: ts.FileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>;
|
||||
private getCanonicalFileName: (fileName: string) => string;
|
||||
|
||||
constructor(private host: ServerHost, private project: Project) {
|
||||
constructor(private host: ServerHost, private project: Project, private cancellationToken: HostCancellationToken) {
|
||||
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.resolvedModuleNames = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
this.resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
@@ -188,6 +188,10 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getCancellationToken() {
|
||||
return this.cancellationToken;
|
||||
}
|
||||
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective, m => m.resolvedTypeReferenceDirective);
|
||||
}
|
||||
@@ -316,7 +320,7 @@ namespace ts.server {
|
||||
compilerOptions.allowNonTsExtensions = true;
|
||||
}
|
||||
|
||||
this.lsHost = new LSHost(this.projectService.host, this);
|
||||
this.lsHost = new LSHost(this.projectService.host, this, this.projectService.cancellationToken);
|
||||
this.lsHost.setCompilationSettings(compilerOptions);
|
||||
this.languageService = ts.createLanguageService(this.lsHost, documentRegistry);
|
||||
}
|
||||
@@ -642,7 +646,10 @@ namespace ts.server {
|
||||
|
||||
private documentRegistry: ts.DocumentRegistry;
|
||||
|
||||
constructor(public host: ServerHost, public psLogger: Logger, public eventHandler?: ProjectServiceEventHandler) {
|
||||
constructor(public host: ServerHost,
|
||||
public psLogger: Logger,
|
||||
public cancellationToken: HostCancellationToken,
|
||||
public eventHandler?: ProjectServiceEventHandler) {
|
||||
// ts.disableIncrementalParsing = true;
|
||||
this.setDefaultHostConfiguration();
|
||||
this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames, host.getCurrentDirectory());
|
||||
|
||||
@@ -92,8 +92,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
constructor(host: ServerHost, logger: ts.server.Logger) {
|
||||
super(host, Buffer.byteLength, process.hrtime, logger);
|
||||
constructor(host: ServerHost, cancellationToken: HostCancellationToken, logger: ts.server.Logger) {
|
||||
super(host, cancellationToken, Buffer.byteLength, process.hrtime, logger);
|
||||
}
|
||||
|
||||
exit() {
|
||||
@@ -294,7 +294,21 @@ namespace ts.server {
|
||||
sys.setTimeout = setTimeout;
|
||||
sys.clearTimeout = clearTimeout;
|
||||
|
||||
const ioSession = new IOSession(sys, logger);
|
||||
let cancellationToken: HostCancellationToken;
|
||||
try {
|
||||
let cancellationPipeName: string;
|
||||
if (cancellationPipeName) {
|
||||
const factory = require("./cancellationToken");
|
||||
cancellationToken = factory(sys.args);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
cancellationToken = {
|
||||
isCancellationRequested: () => false
|
||||
}
|
||||
}
|
||||
|
||||
const ioSession = new IOSession(sys, cancellationToken, logger);
|
||||
process.on("uncaughtException", function(err: Error) {
|
||||
ioSession.logError(err, "unknown");
|
||||
});
|
||||
|
||||
@@ -156,12 +156,12 @@ namespace ts.server {
|
||||
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
private cancellationToken: HostCancellationToken,
|
||||
private byteLength: (buf: string, encoding?: string) => number,
|
||||
private hrtime: (start?: number[]) => number[],
|
||||
private logger: Logger
|
||||
) {
|
||||
private logger: Logger) {
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName, project, fileName) => {
|
||||
new ProjectService(host, logger, cancellationToken, (eventName, project, fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
}
|
||||
@@ -1067,6 +1067,10 @@ namespace ts.server {
|
||||
return { response, responseRequired: true };
|
||||
}
|
||||
|
||||
private canceledResponse() {
|
||||
return { canceled: true, responseRequired: true };
|
||||
}
|
||||
|
||||
private handlers: Map<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = {
|
||||
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
|
||||
this.projectService.openExternalProject(request.arguments);
|
||||
@@ -1282,6 +1286,8 @@ namespace ts.server {
|
||||
catch (err) {
|
||||
if (err instanceof OperationCanceledException) {
|
||||
// Handle cancellation exceptions
|
||||
this.output({ canceled: true }, request.command, request.seq);
|
||||
return;
|
||||
}
|
||||
this.logError(err, message);
|
||||
this.output(
|
||||
|
||||
Reference in New Issue
Block a user