Merge branch 'master' into completionListWithLocalName
Conflicts: tests/cases/fourslash/renameLocationsForClassExpression01.ts
This commit is contained in:
commit
872fdcf444
|
@ -892,7 +892,8 @@ namespace ts {
|
|||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, "__function");
|
||||
let bindingName = (<FunctionExpression>node).name ? (<FunctionExpression>node).name.text : "__function";
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, bindingName);
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return bindClassLikeDeclaration(<ClassLikeDeclaration>node);
|
||||
|
@ -964,7 +965,8 @@ namespace ts {
|
|||
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
}
|
||||
else {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Class, "__class");
|
||||
let bindingName = node.name ? node.name.text : "__class";
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
||||
}
|
||||
|
||||
let symbol = node.symbol;
|
||||
|
|
|
@ -22,6 +22,17 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker {
|
||||
// Cancellation that controls whether or not we can cancel in the middle of type checking.
|
||||
// In general cancelling is *not* safe for the type checker. We might be in the middle of
|
||||
// computing something, and we will leave our internals in an inconsistent state. Callers
|
||||
// who set the cancellation token should catch if a cancellation exception occurs, and
|
||||
// should throw away and create a new TypeChecker.
|
||||
//
|
||||
// Currently we only support setting the cancellation token when getting diagnostics. This
|
||||
// is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
|
||||
// they no longer need the information (for example, if the user started editing again).
|
||||
let cancellationToken: CancellationToken;
|
||||
|
||||
let Symbol = objectAllocator.getSymbolConstructor();
|
||||
let Type = objectAllocator.getTypeConstructor();
|
||||
let Signature = objectAllocator.getSignatureConstructor();
|
||||
|
@ -194,10 +205,10 @@ namespace ts {
|
|||
|
||||
return checker;
|
||||
|
||||
function getEmitResolver(sourceFile?: SourceFile) {
|
||||
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);
|
||||
getDiagnostics(sourceFile, cancellationToken);
|
||||
return emitResolver;
|
||||
}
|
||||
|
||||
|
@ -13028,8 +13039,24 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkSourceElement(node: Node): void {
|
||||
if (!node) return;
|
||||
switch (node.kind) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
let kind = node.kind;
|
||||
if (cancellationToken) {
|
||||
// Only bother checking on a few construct kinds. We don't want to be excessivly
|
||||
// hitting the cancellation token on every node we check.
|
||||
switch (kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.TypeParameter:
|
||||
return checkTypeParameter(<TypeParameterDeclaration>node);
|
||||
case SyntaxKind.Parameter:
|
||||
|
@ -13305,7 +13332,20 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
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
|
||||
// this call is done.
|
||||
cancellationToken = ct;
|
||||
return getDiagnosticsWorker(sourceFile);
|
||||
}
|
||||
finally {
|
||||
cancellationToken = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getDiagnosticsWorker(sourceFile: SourceFile): Diagnostic[] {
|
||||
throwIfNonDiagnosticsProducing();
|
||||
if (sourceFile) {
|
||||
checkSourceFile(sourceFile);
|
||||
|
|
|
@ -1246,6 +1246,11 @@ namespace ts {
|
|||
return isIdentifier();
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrKeyword() {
|
||||
nextToken();
|
||||
return isIdentifierOrKeyword();
|
||||
}
|
||||
|
||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||
if (token === SyntaxKind.ImplementsKeyword ||
|
||||
token === SyntaxKind.ExtendsKeyword) {
|
||||
|
@ -3172,7 +3177,7 @@ namespace ts {
|
|||
if (sourceFile.languageVariant !== LanguageVariant.JSX) {
|
||||
return parseTypeAssertion();
|
||||
}
|
||||
if(lookAhead(nextTokenIsIdentifier)) {
|
||||
if(lookAhead(nextTokenIsIdentifierOrKeyword)) {
|
||||
return parseJsxElementOrSelfClosingElement();
|
||||
}
|
||||
// Fall through
|
||||
|
@ -3390,7 +3395,7 @@ namespace ts {
|
|||
|
||||
function parseJsxElementName(): EntityName {
|
||||
scanJsxIdentifier();
|
||||
let elementName: EntityName = parseIdentifier();
|
||||
let elementName: EntityName = parseIdentifierName();
|
||||
while (parseOptional(SyntaxKind.DotToken)) {
|
||||
scanJsxIdentifier();
|
||||
let node = <QualifiedName>createNode(SyntaxKind.QualifiedName, elementName.pos);
|
||||
|
|
|
@ -104,14 +104,14 @@ namespace ts {
|
|||
};
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile): Diagnostic[] {
|
||||
let diagnostics = program.getOptionsDiagnostics().concat(
|
||||
program.getSyntacticDiagnostics(sourceFile),
|
||||
program.getGlobalDiagnostics(),
|
||||
program.getSemanticDiagnostics(sourceFile));
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
diagnostics.concat(program.getDeclarationDiagnostics(sourceFile));
|
||||
diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
return sortAndDeduplicateDiagnostics(diagnostics);
|
||||
|
@ -233,10 +233,15 @@ namespace ts {
|
|||
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
|
||||
}
|
||||
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback): 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: CancellationToken): EmitResult {
|
||||
// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
|
||||
// immediately bail out.
|
||||
if (options.noEmitOnError && getPreEmitDiagnostics(this).length > 0) {
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
if (options.noEmitOnError && getPreEmitDiagnostics(program, /*sourceFile:*/ undefined, cancellationToken).length > 0) {
|
||||
return { diagnostics: [], sourceMaps: undefined, emitSkipped: true };
|
||||
}
|
||||
|
||||
|
@ -265,53 +270,86 @@ namespace ts {
|
|||
return filesByName.get(fileName);
|
||||
}
|
||||
|
||||
function getDiagnosticsHelper(sourceFile: SourceFile, getDiagnostics: (sourceFile: SourceFile) => Diagnostic[]): Diagnostic[] {
|
||||
function getDiagnosticsHelper(
|
||||
sourceFile: SourceFile,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[],
|
||||
cancellationToken: CancellationToken): Diagnostic[] {
|
||||
if (sourceFile) {
|
||||
return getDiagnostics(sourceFile);
|
||||
return getDiagnostics(sourceFile, cancellationToken);
|
||||
}
|
||||
|
||||
let allDiagnostics: Diagnostic[] = [];
|
||||
forEach(program.getSourceFiles(), sourceFile => {
|
||||
addRange(allDiagnostics, getDiagnostics(sourceFile));
|
||||
if (cancellationToken) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
addRange(allDiagnostics, getDiagnostics(sourceFile, cancellationToken));
|
||||
});
|
||||
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
}
|
||||
|
||||
function getSyntacticDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile);
|
||||
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getSemanticDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile);
|
||||
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getDeclarationDiagnostics(sourceFile?: SourceFile): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile);
|
||||
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return sourceFile.parseDiagnostics;
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
function runWithCancellationToken<T>(func: () => T): T {
|
||||
try {
|
||||
return func();
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof OperationCanceledException) {
|
||||
// We were canceled while performing the operation. Because our type checker
|
||||
// might be a bad state, we need to throw it away.
|
||||
//
|
||||
// Note: we are overly agressive here. We do not actually *have* to throw away
|
||||
// the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep
|
||||
// the lifetimes of these two TypeCheckers the same. Also, we generally only
|
||||
// cancel when the user has made a change anyways. And, in that case, we (the
|
||||
// program instance) will get thrown away anyways. So trying to keep one of
|
||||
// these type checkers alive doesn't serve much purpose.
|
||||
noDiagnosticsTypeChecker = undefined;
|
||||
diagnosticsProducingTypeChecker = undefined;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
let typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
let bindDiagnostics = sourceFile.bindDiagnostics;
|
||||
let checkDiagnostics = typeChecker.getDiagnostics(sourceFile);
|
||||
let checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
let programDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
return bindDiagnostics.concat(checkDiagnostics).concat(programDiagnostics);
|
||||
});
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
if (!isDeclarationFile(sourceFile)) {
|
||||
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile);
|
||||
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||
// Don't actually write any files since we're just getting diagnostics.
|
||||
var writeFile: WriteFileCallback = () => { };
|
||||
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
|
|
|
@ -1290,6 +1290,15 @@ namespace ts {
|
|||
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
|
||||
}
|
||||
|
||||
export class OperationCanceledException { }
|
||||
|
||||
export interface CancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
|
||||
/** @throws OperationCanceledException if isCancellationRequested is true */
|
||||
throwIfCancellationRequested(): void;
|
||||
}
|
||||
|
||||
export interface Program extends ScriptReferenceHost {
|
||||
/**
|
||||
* Get a list of files in the program
|
||||
|
@ -1306,13 +1315,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): EmitResult;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult;
|
||||
|
||||
getOptionsDiagnostics(): Diagnostic[];
|
||||
getGlobalDiagnostics(): Diagnostic[];
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile): 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.
|
||||
|
@ -1423,9 +1432,9 @@ namespace ts {
|
|||
getJsxIntrinsicTagNames(): Symbol[];
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
|
||||
/* @internal */ getEmitResolver(sourceFile?: SourceFile): EmitResolver;
|
||||
/* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
|
||||
|
||||
/* @internal */ getNodeCount(): number;
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
|
@ -2178,14 +2187,9 @@ namespace ts {
|
|||
verticalTab = 0x0B, // \v
|
||||
}
|
||||
|
||||
export interface CancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,7 +121,7 @@ module Harness.LanguageService {
|
|||
export class LanguageServiceAdapterHost {
|
||||
protected fileNameToScript: ts.Map<ScriptInfo> = {};
|
||||
|
||||
constructor(protected cancellationToken: ts.CancellationToken = CancellationToken.None,
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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[] = [];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -1618,26 +1622,6 @@ 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache host information about scrip Should be refreshed
|
||||
// at each language service public entry point, since we don't know when
|
||||
// set of scripts handled by the host changes.
|
||||
|
@ -2404,6 +2388,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;
|
||||
|
@ -2608,7 +2607,7 @@ namespace ts {
|
|||
function getSyntacticDiagnostics(fileName: string) {
|
||||
synchronizeHostData();
|
||||
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName));
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2630,13 +2629,13 @@ namespace ts {
|
|||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile);
|
||||
let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
|
||||
if (!program.getCompilerOptions().declaration) {
|
||||
return semanticDiagnostics;
|
||||
}
|
||||
|
||||
// If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
|
||||
let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile);
|
||||
let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
|
||||
return concatenate(semanticDiagnostics, declarationDiagnostics);
|
||||
}
|
||||
|
||||
|
@ -2799,7 +2798,8 @@ namespace ts {
|
|||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
return program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getGlobalDiagnostics(cancellationToken));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3029,21 +3029,30 @@ namespace ts {
|
|||
let objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
|
||||
let jsxContainer = tryGetContainingJsxElement(contextToken);
|
||||
if (objectLikeContainer) {
|
||||
// Object literal expression, look up possible property names from contextual type
|
||||
// We're looking up possible property names from contextual/inferred/declared type.
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = true;
|
||||
|
||||
let typeForObject: Type;
|
||||
let existingMembers: Declaration[];
|
||||
|
||||
if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
// We are completing on contextual types, but may also include properties
|
||||
// other than those within the declared type.
|
||||
isNewIdentifierLocation = true;
|
||||
|
||||
typeForObject = typeChecker.getContextualType(<ObjectLiteralExpression>objectLikeContainer);
|
||||
existingMembers = (<ObjectLiteralExpression>objectLikeContainer).properties;
|
||||
}
|
||||
else {
|
||||
else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
// We are *only* completing on properties from the type being destructured.
|
||||
isNewIdentifierLocation = false;
|
||||
|
||||
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
|
||||
existingMembers = (<BindingPattern>objectLikeContainer).elements;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);
|
||||
}
|
||||
|
||||
if (!typeForObject) {
|
||||
return false;
|
||||
|
@ -5842,7 +5851,7 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
let emitOutput = program.emit(sourceFile, writeFile);
|
||||
let emitOutput = program.emit(sourceFile, writeFile, cancellationToken);
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
|
@ -6090,6 +6099,26 @@ namespace ts {
|
|||
return convertClassifications(getEncodedSemanticClassifications(fileName, span));
|
||||
}
|
||||
|
||||
function checkForClassificationCancellation(kind: SyntaxKind) {
|
||||
// We don't want to actually call back into our host on every node to find out if we've
|
||||
// been canceled. That would be an enormous amount of chattyness, along with the all
|
||||
// the overhead of marshalling the data to/from the host. So instead we pick a few
|
||||
// reasonable node kinds to bother checking on. These node kinds represent high level
|
||||
// constructs that we would expect to see commonly, but just at a far less frequent
|
||||
// interval.
|
||||
//
|
||||
// For example, in checker.ts (around 750k) we only have around 600 of these constructs.
|
||||
// That means we're calling back into the host around every 1.2k of the file we process.
|
||||
// Lib.d.ts has similar numbers.
|
||||
switch (kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
synchronizeHostData();
|
||||
|
||||
|
@ -6157,7 +6186,10 @@ namespace ts {
|
|||
function processNode(node: Node) {
|
||||
// Only walk into nodes that intersect the requested span.
|
||||
if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) {
|
||||
if (node.kind === SyntaxKind.Identifier && !nodeIsMissing(node)) {
|
||||
let kind = node.kind;
|
||||
checkForClassificationCancellation(kind);
|
||||
|
||||
if (kind === SyntaxKind.Identifier && !nodeIsMissing(node)) {
|
||||
let identifier = <Identifier>node;
|
||||
|
||||
// Only bother calling into the typechecker if this is an identifier that
|
||||
|
@ -6524,6 +6556,8 @@ namespace ts {
|
|||
|
||||
// Ignore nodes that don't intersect the original span to classify.
|
||||
if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
|
||||
checkForClassificationCancellation(element.kind);
|
||||
|
||||
let children = element.getChildren(sourceFile);
|
||||
for (let i = 0, n = children.length; i < n; i++) {
|
||||
let child = children[i];
|
||||
|
|
|
@ -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,8 +326,9 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
public getCancellationToken(): CancellationToken {
|
||||
return this.shimHost.getCancellationToken();
|
||||
public getCancellationToken(): HostCancellationToken {
|
||||
var hostCancellationToken = this.shimHost.getCancellationToken();
|
||||
return new ThrottledCancellationToken(hostCancellationToken);
|
||||
}
|
||||
|
||||
public getCurrentDirectory(): string {
|
||||
|
@ -346,6 +347,29 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/** A cancellation that throttles calls to the host */
|
||||
class ThrottledCancellationToken implements HostCancellationToken {
|
||||
// Store when we last tried to cancel. Checking cancellation can be expensive (as we have
|
||||
// to marshall over to the host layer). So we only bother actually checking once enough
|
||||
// time has passed.
|
||||
private lastCancellationCheckTime = 0;
|
||||
|
||||
constructor(private hostCancellationToken: HostCancellationToken) {
|
||||
}
|
||||
|
||||
public isCancellationRequested(): boolean {
|
||||
var time = Date.now();
|
||||
var duration = Math.abs(time - this.lastCancellationCheckTime);
|
||||
if (duration > 10) {
|
||||
// Check no more than once every 10 ms.
|
||||
this.lastCancellationCheckTime = time;
|
||||
return this.hostCancellationToken.isCancellationRequested();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class CoreServicesShimHostAdapter implements ParseConfigHost {
|
||||
|
||||
constructor(private shimHost: CoreServicesShimHost) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,13 +28,13 @@ function M() {
|
|||
}
|
||||
|
||||
var v = new m<number>();
|
||||
>v : <number>
|
||||
>new m<number>() : <number>
|
||||
>v : C<number>
|
||||
>new m<number>() : C<number>
|
||||
>m : typeof C
|
||||
|
||||
return v.f<string>();
|
||||
>v.f<string>() : { t: string; x: number; }
|
||||
>v.f : <T>() => { t: T; x: number; }
|
||||
>v : <number>
|
||||
>v : C<number>
|
||||
>f : <T>() => { t: T; x: number; }
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(22,8): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(23,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(23,8): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(24,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(25,8): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(25,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(26,8): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(27,8): error TS2339: Property 'var' does not exist on type 'Attribs1'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(29,1): error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'.
|
||||
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/tsxAttributeResolution1.tsx (6 errors) ====
|
||||
==== tests/cases/conformance/jsx/tsxAttributeResolution1.tsx (7 errors) ====
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
test1: Attribs1;
|
||||
test2: { reqd: string };
|
||||
var: { var: string };
|
||||
}
|
||||
}
|
||||
interface Attribs1 {
|
||||
|
@ -40,8 +42,9 @@ tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Typ
|
|||
<test1 x="32" />; // Error, "32" is not number
|
||||
~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
// TODO attribute 'var' should be parseable
|
||||
// <test1 var="10" />; // Error, no 'var' property
|
||||
<test1 var="10" />; // Error, no 'var' property
|
||||
~~~
|
||||
!!! error TS2339: Property 'var' does not exist on type 'Attribs1'.
|
||||
|
||||
<test2 />; // Error, missing reqd
|
||||
~~~~~~~~~
|
||||
|
@ -50,4 +53,6 @@ tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Typ
|
|||
~~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
// Should be OK
|
||||
<var var='var' />;
|
||||
|
|
@ -4,6 +4,7 @@ declare module JSX {
|
|||
interface IntrinsicElements {
|
||||
test1: Attribs1;
|
||||
test2: { reqd: string };
|
||||
var: { var: string };
|
||||
}
|
||||
}
|
||||
interface Attribs1 {
|
||||
|
@ -24,12 +25,13 @@ interface Attribs1 {
|
|||
<test1 y={0} />; // Error, no property "y"
|
||||
<test1 y="foo" />; // Error, no property "y"
|
||||
<test1 x="32" />; // Error, "32" is not number
|
||||
// TODO attribute 'var' should be parseable
|
||||
// <test1 var="10" />; // Error, no 'var' property
|
||||
<test1 var="10" />; // Error, no 'var' property
|
||||
|
||||
<test2 />; // Error, missing reqd
|
||||
<test2 reqd={10} />; // Error, reqd is not string
|
||||
|
||||
// Should be OK
|
||||
<var var='var' />;
|
||||
|
||||
|
||||
//// [tsxAttributeResolution1.jsx]
|
||||
|
@ -44,7 +46,8 @@ interface Attribs1 {
|
|||
<test1 y={0}/>; // Error, no property "y"
|
||||
<test1 y="foo"/>; // Error, no property "y"
|
||||
<test1 x="32"/>; // Error, "32" is not number
|
||||
// TODO attribute 'var' should be parseable
|
||||
// <test1 var="10" />; // Error, no 'var' property
|
||||
<test1 var="10"/>; // Error, no 'var' property
|
||||
<test2 />; // Error, missing reqd
|
||||
<test2 reqd={10}/>; // Error, reqd is not string
|
||||
// Should be OK
|
||||
<var var='var'/>;
|
||||
|
|
|
@ -5,6 +5,7 @@ declare module JSX {
|
|||
interface IntrinsicElements {
|
||||
test1: Attribs1;
|
||||
test2: { reqd: string };
|
||||
var: { var: string };
|
||||
}
|
||||
}
|
||||
interface Attribs1 {
|
||||
|
@ -25,9 +26,10 @@ interface Attribs1 {
|
|||
<test1 y={0} />; // Error, no property "y"
|
||||
<test1 y="foo" />; // Error, no property "y"
|
||||
<test1 x="32" />; // Error, "32" is not number
|
||||
// TODO attribute 'var' should be parseable
|
||||
// <test1 var="10" />; // Error, no 'var' property
|
||||
<test1 var="10" />; // Error, no 'var' property
|
||||
|
||||
<test2 />; // Error, missing reqd
|
||||
<test2 reqd={10} />; // Error, reqd is not string
|
||||
|
||||
// Should be OK
|
||||
<var var='var' />;
|
||||
|
|
|
@ -11,3 +11,4 @@
|
|||
goTo.marker();
|
||||
verify.completionListContains("property1");
|
||||
verify.completionListContains("property2");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -11,3 +11,4 @@
|
|||
goTo.marker();
|
||||
verify.completionListContains("property2");
|
||||
verify.not.completionListContains("property1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -11,3 +11,4 @@
|
|||
goTo.marker();
|
||||
verify.completionListContains("property1");
|
||||
verify.completionListContains("property2");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -10,3 +10,4 @@
|
|||
|
||||
goTo.marker();
|
||||
verify.completionListContains("property1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -16,3 +16,4 @@ goTo.marker();
|
|||
verify.completionListContains("propertyOfI_1");
|
||||
verify.completionListContains("propertyOfI_2");
|
||||
verify.not.completionListContains("property2");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -16,3 +16,4 @@ goTo.marker();
|
|||
verify.completionListContains("propertyOfI_2");
|
||||
verify.not.completionListContains("propertyOfI_1");
|
||||
verify.not.completionListContains("property2");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -17,3 +17,4 @@ verify.completionListContains("property2");
|
|||
verify.not.completionListContains("property1");
|
||||
verify.not.completionListContains("propertyOfI_2");
|
||||
verify.not.completionListContains("propertyOfI_1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -17,7 +17,9 @@ verify.completionListContains("property2");
|
|||
verify.not.completionListContains("property1");
|
||||
verify.not.completionListContains("propertyOfI_2");
|
||||
verify.not.completionListContains("propertyOfI_1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
||||
|
||||
goTo.marker("2");
|
||||
verify.completionListContains("property1");
|
||||
verify.completionListContains("property2");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -11,3 +11,4 @@ goTo.marker("");
|
|||
verify.completionListContains("property2");
|
||||
verify.not.completionListContains("property1");
|
||||
verify.not.completionListContains("prop1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -11,3 +11,4 @@
|
|||
goTo.marker("");
|
||||
verify.completionListContains("property2");
|
||||
verify.not.completionListContains("property1");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -17,3 +17,4 @@ goTo.marker();
|
|||
verify.completionListContains("x");
|
||||
verify.completionListContains("y");
|
||||
verify.not.completionListContains("z");
|
||||
verify.not.completionListAllowsNewIdentifier();
|
|
@ -3,7 +3,6 @@
|
|||
////class Foo {
|
||||
////}
|
||||
////
|
||||
//////The class expression Foo
|
||||
////var x = class [|Foo|] {
|
||||
//// doIt() {
|
||||
//// return [|Foo|];
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////module M {
|
||||
////}
|
||||
////module N {
|
||||
////}
|
||||
|
||||
var c = classification;
|
||||
cancellation.setCancelled(1);
|
||||
verifyOperationIsCancelled(() => verify.semanticClassificationsAre());
|
||||
cancellation.resetCancelled();
|
||||
|
||||
verify.semanticClassificationsAre(
|
||||
c.moduleName("M"),
|
||||
c.moduleName("N"));
|
|
@ -1,38 +0,0 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//@Filename: findAllRefsOnDefinition-import.ts
|
||||
////export class Test{
|
||||
////
|
||||
//// constructor(){
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//// public /*1*/start(){
|
||||
//// return this;
|
||||
//// }
|
||||
////
|
||||
//// public stop(){
|
||||
//// return this;
|
||||
//// }
|
||||
////}
|
||||
|
||||
//@Filename: findAllRefsOnDefinition.ts
|
||||
////import Second = require("findAllRefsOnDefinition-import");
|
||||
////
|
||||
////var second = new Second.Test()
|
||||
////second.start();
|
||||
////second.stop();
|
||||
|
||||
goTo.file("findAllRefsOnDefinition-import.ts");
|
||||
goTo.marker("1");
|
||||
|
||||
verify.referencesCountIs(2);
|
||||
|
||||
cancellation.setCancelled();
|
||||
goTo.marker("1");
|
||||
verifyOperationIsCancelled(() => verify.referencesCountIs(0) );
|
||||
|
||||
// verify that internal state is still correct
|
||||
cancellation.resetCancelled();
|
||||
goTo.marker("1");
|
||||
verify.referencesCountIs(2);
|
|
@ -0,0 +1,21 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////module M {
|
||||
////}
|
||||
////module N {
|
||||
////}
|
||||
|
||||
var c = classification;
|
||||
cancellation.setCancelled(1);
|
||||
verifyOperationIsCancelled(() => verify.syntacticClassificationsAre());
|
||||
cancellation.resetCancelled();
|
||||
|
||||
verify.syntacticClassificationsAre(
|
||||
c.keyword("module"),
|
||||
c.moduleName("M"),
|
||||
c.punctuation("{"),
|
||||
c.punctuation("}"),
|
||||
c.keyword("module"),
|
||||
c.moduleName("N"),
|
||||
c.punctuation("{"),
|
||||
c.punctuation("}"));
|
Loading…
Reference in a new issue