diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0fcc478d2b1..8fd7f1a75d9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -167,7 +167,7 @@ namespace ts { return checker; - function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationTokenObject) { + function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) { // Ensure we have all the type information in place for this file so that all the // emitter questions of this resolver will return the right information. getDiagnostics(sourceFile, cancellationToken); @@ -11681,8 +11681,8 @@ namespace ts { } } - var cancellationToken: CancellationTokenObject; - function getDiagnostics(sourceFile: SourceFile, ct: CancellationTokenObject): Diagnostic[] { + var cancellationToken: CancellationToken; + function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken): Diagnostic[] { try { // Record the cancellation token so it can be checked later on during checkSourceElement. // Do this in a finally block so we can ensure that it gets reset back to nothing after diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 49371dbccd2..52eae6e37c1 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -798,25 +798,4 @@ namespace ts { Debug.assert(false, message); } } -} - -namespace ts { - export class OperationCanceledException { } - - export class CancellationTokenObject { - public static None: CancellationTokenObject = new CancellationTokenObject(null) - - constructor(private cancellationToken: CancellationToken) { - } - - public isCancellationRequested() { - return this.cancellationToken && this.cancellationToken.isCancellationRequested(); - } - - public throwIfCancellationRequested(): void { - if (this.isCancellationRequested()) { - throw new OperationCanceledException(); - } - } - } } \ No newline at end of file diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 443f5f92b49..f0277e60d0d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -104,7 +104,7 @@ namespace ts { }; } - export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): Diagnostic[] { + export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] { let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat( program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), @@ -233,11 +233,11 @@ namespace ts { return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false)); } - function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationTokenObject): EmitResult { + function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult { return runWithCancellationToken(() => emitWorker(this, sourceFile, writeFileCallback, cancellationToken)); } - function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationTokenObject): EmitResult { + function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken): EmitResult { // If the noEmitOnError flag is set, then check if we have any errors so far. If so, // immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we // get any preEmit diagnostics, not just the ones @@ -272,8 +272,8 @@ namespace ts { function getDiagnosticsHelper( sourceFile: SourceFile, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationTokenObject) => Diagnostic[], - cancellationToken: CancellationTokenObject): Diagnostic[] { + getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[], + cancellationToken: CancellationToken): Diagnostic[] { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } @@ -289,19 +289,19 @@ namespace ts { return sortAndDeduplicateDiagnostics(allDiagnostics); } - function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken); } - function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken); } - function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken); } - function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return sourceFile.parseDiagnostics; } @@ -321,7 +321,7 @@ namespace ts { } } - function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { let typeChecker = getDiagnosticsProducingTypeChecker(); @@ -334,7 +334,7 @@ namespace ts { }); } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationTokenObject): Diagnostic[] { + function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { if (!isDeclarationFile(sourceFile)) { let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 799c291f46a..662c10f4235 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1210,13 +1210,13 @@ namespace ts { * used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter * will be invoked when writing the JavaScript and declaration files. */ - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationTokenObject): EmitResult; + emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult; - getOptionsDiagnostics(cancellationToken?: CancellationTokenObject): Diagnostic[]; - getGlobalDiagnostics(cancellationToken?: CancellationTokenObject): Diagnostic[]; - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): Diagnostic[]; - getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): Diagnostic[]; - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): Diagnostic[]; + getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; + getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; + getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; /** * Gets a type checker that can be used to semantically analyze source fils in the program. @@ -1324,9 +1324,9 @@ namespace ts { getExportsOfModule(moduleSymbol: Symbol): Symbol[]; // Should not be called directly. Should only be accessed through the Program instance. - /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): Diagnostic[]; + /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; /* @internal */ getGlobalDiagnostics(): Diagnostic[]; - /* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationTokenObject): EmitResolver; + /* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver; /* @internal */ getNodeCount(): number; /* @internal */ getIdentifierCount(): number; @@ -2052,14 +2052,18 @@ namespace ts { verticalTab = 0x0B, // \v } + export class OperationCanceledException { } + export interface CancellationToken { isCancellationRequested(): boolean; + + /** @throws OperationCanceledException if isCancellationRequested is true */ + throwIfCancellationRequested(): void; } export interface CompilerHost { getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile; getDefaultLibFileName(options: CompilerOptions): string; - getCancellationToken? (): CancellationToken; writeFile: WriteFileCallback; getCurrentDirectory(): string; getCanonicalFileName(fileName: string): string; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 5915698462c..41dda5bc9b3 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -190,14 +190,14 @@ module FourSlash { return "\nMarker: " + currentTestState.lastKnownMarker + "\nChecking: " + msg + "\n\n"; } - export class TestCancellationToken implements ts.CancellationToken { + export class TestCancellationToken implements ts.HostCancellationToken { // 0 - cancelled // >0 - not cancelled // <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled - private static NotCancelled: number = -1; - private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCancelled; - public isCancellationRequested(): boolean { + private static NotCanceled: number = -1; + private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled; + public isCancellationRequested(): boolean { if (this.numberOfCallsBeforeCancellation < 0) { return false; } @@ -216,7 +216,7 @@ module FourSlash { } public resetCancelled(): void { - this.numberOfCallsBeforeCancellation = TestCancellationToken.NotCancelled; + this.numberOfCallsBeforeCancellation = TestCancellationToken.NotCanceled; } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 8eb77817533..6cb92df5948 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -103,14 +103,11 @@ module Harness.LanguageService { } } - class CancellationToken { - public static None: CancellationToken = new CancellationToken(null); - - constructor(private cancellationToken: ts.CancellationToken) { - } + class DefaultHostCancellationToken implements ts.HostCancellationToken { + public static Instance = new DefaultHostCancellationToken(); public isCancellationRequested() { - return this.cancellationToken && this.cancellationToken.isCancellationRequested(); + return false; } } @@ -124,8 +121,8 @@ module Harness.LanguageService { export class LanguageServiceAdapterHost { protected fileNameToScript: ts.Map = {}; - constructor(protected cancellationToken: ts.CancellationToken = CancellationToken.None, - protected settings = ts.getDefaultCompilerOptions()) { + constructor(protected cancellationToken = DefaultHostCancellationToken.Instance, + protected settings = ts.getDefaultCompilerOptions()) { } public getNewLine(): string { @@ -173,8 +170,8 @@ module Harness.LanguageService { /// Native adapter class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost { - getCompilationSettings(): ts.CompilerOptions { return this.settings; } - getCancellationToken(): ts.CancellationToken { return this.cancellationToken; } + getCompilationSettings() { return this.settings; } + getCancellationToken() { return this.cancellationToken; } getCurrentDirectory(): string { return ""; } getDefaultLibFileName(): string { return ""; } getScriptFileNames(): string[] { return this.getFilenames(); } @@ -194,7 +191,7 @@ module Harness.LanguageService { export class NativeLanugageServiceAdapter implements LanguageServiceAdapter { private host: NativeLanguageServiceHost; - constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { this.host = new NativeLanguageServiceHost(cancellationToken, options); } getHost() { return this.host; } @@ -206,7 +203,7 @@ module Harness.LanguageService { /// Shim adapter class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost, ts.CoreServicesShimHost { private nativeHost: NativeLanguageServiceHost; - constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { super(cancellationToken, options); this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options); } @@ -218,7 +215,7 @@ module Harness.LanguageService { positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter { return this.nativeHost.positionToLineAndCharacter(fileName, position); } getCompilationSettings(): string { return JSON.stringify(this.nativeHost.getCompilationSettings()); } - getCancellationToken(): ts.CancellationToken { return this.nativeHost.getCancellationToken(); } + getCancellationToken(): ts.HostCancellationToken { return this.nativeHost.getCancellationToken(); } getCurrentDirectory(): string { return this.nativeHost.getCurrentDirectory(); } getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); } getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); } @@ -399,7 +396,7 @@ module Harness.LanguageService { export class ShimLanugageServiceAdapter implements LanguageServiceAdapter { private host: ShimLanguageServiceHost; private factory: ts.TypeScriptServicesFactory; - constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { this.host = new ShimLanguageServiceHost(cancellationToken, options); this.factory = new TypeScript.Services.TypeScriptServicesFactory(); } @@ -446,7 +443,7 @@ module Harness.LanguageService { class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost { private client: ts.server.SessionClient; - constructor(cancellationToken: ts.CancellationToken, settings: ts.CompilerOptions) { + constructor(cancellationToken: ts.HostCancellationToken, settings: ts.CompilerOptions) { super(cancellationToken, settings); } @@ -575,7 +572,7 @@ module Harness.LanguageService { export class ServerLanugageServiceAdapter implements LanguageServiceAdapter { private host: SessionClientHost; private client: ts.server.SessionClient; - constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { // This is the main host that tests use to direct tests var clientHost = new SessionClientHost(cancellationToken, options); var client = new ts.server.SessionClient(clientHost); diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index a4cc7ec2ad5..bc506bc22f9 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -2,7 +2,7 @@ namespace ts.NavigateTo { type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration }; - export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[] { + export function getNavigateToItems(program: Program, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number): NavigateToItem[] { let patternMatcher = createPatternMatcher(searchValue); let rawItems: RawNavigateToItem[] = []; diff --git a/src/services/services.ts b/src/services/services.ts index f7f7dfcf6b3..efb7a61a8dd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -944,6 +944,10 @@ namespace ts { } } + export interface HostCancellationToken { + isCancellationRequested(): boolean; + } + // // Public interface of the host of a language service instance. // @@ -955,7 +959,7 @@ namespace ts { getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): IScriptSnapshot; getLocalizedDiagnosticMessages?(): any; - getCancellationToken?(): CancellationToken; + getCancellationToken?(): HostCancellationToken; getCurrentDirectory(): string; getDefaultLibFileName(options: CompilerOptions): string; log? (s: string): void; @@ -2379,6 +2383,21 @@ namespace ts { return ScriptElementKind.unknown; } + class CancellationTokenObject implements CancellationToken { + constructor(private cancellationToken: HostCancellationToken) { + } + + public isCancellationRequested() { + return this.cancellationToken && this.cancellationToken.isCancellationRequested(); + } + + public throwIfCancellationRequested(): void { + if (this.isCancellationRequested()) { + throw new OperationCanceledException(); + } + } + } + export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry()): LanguageService { let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; diff --git a/src/services/shims.ts b/src/services/shims.ts index 2e8b3eb774d..f56cef82f9d 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -51,7 +51,7 @@ namespace ts { getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): ScriptSnapshotShim; getLocalizedDiagnosticMessages(): string; - getCancellationToken(): CancellationToken; + getCancellationToken(): HostCancellationToken; getCurrentDirectory(): string; getDefaultLibFileName(options: string): string; getNewLine?(): string; @@ -326,7 +326,7 @@ namespace ts { } } - public getCancellationToken(): CancellationToken { + public getCancellationToken(): HostCancellationToken { return this.shimHost.getCancellationToken(); } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index fce4e2c3025..44b022a7b12 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -178,7 +178,7 @@ namespace ts.SignatureHelp { argumentCount: number; } - export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, cancellationToken: CancellationTokenObject): SignatureHelpItems { + export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, cancellationToken: CancellationToken): SignatureHelpItems { let typeChecker = program.getTypeChecker(); // Decide whether to show signature help