diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index cb9d95868ae..92be81ba3f2 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1680,13 +1680,13 @@ namespace FourSlash { assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count")); } - public verifyImplementationsCount(negative: boolean, expectedCount: number) { + public verifyImplementationListIsEmpty(negative: boolean) { const assertFn = negative ? assert.notEqual : assert.equal; const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); const actualCount = implementations && implementations.length || 0; - assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Implementations Count")); + assertFn(actualCount, 0, this.messageAtLastKnownMarker("Implementations Count")); } public verifyGoToDefinitionName(expectedName: string, expectedContainerName: string) { @@ -1697,26 +1697,22 @@ namespace FourSlash { assert.equal(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name")); } - public goToImplementation(implIndex?: number) { + public goToImplementation() { const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("goToImplementation failed - expected to find at least one implementation location but got 0"); } - - if (implIndex === undefined && implementations.length > 1) { - this.raiseError(`goToImplementation failed - no index given but more than 1 implementation returned (${implementations.length})`); + if (implementations.length > 1) { + this.raiseError(`goToImplementation failed - more than 1 implementation returned (${implementations.length})`); } - if (implIndex >= implementations.length) { - this.raiseError(`goToImplementation failed - implIndex value (${implIndex}) exceeds implementation list size (${implementations.length})`); - } - - const implementation = implementations[implIndex || 0]; + const implementation = implementations[0]; this.openFile(implementation.fileName); this.currentCaretPosition = implementation.textSpan.start; } - public verifyRangesInImplementationList() { + public verifyRangesInImplementationList(markerName: string) { + this.goToMarker(markerName); const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!implementations || !implementations.length) { this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0"); @@ -2954,8 +2950,8 @@ namespace FourSlashInterface { this.state.goToTypeDefinition(definitionIndex); } - public implementation(implementationIndex?: number) { - this.state.goToImplementation(implementationIndex); + public implementation() { + this.state.goToImplementation(); } public position(position: number, fileIndex?: number): void; @@ -3062,8 +3058,8 @@ namespace FourSlashInterface { this.state.verifyTypeDefinitionsCount(this.negative, expectedCount); } - public implementationCountIs(expectedCount: number) { - this.state.verifyImplementationsCount(this.negative, expectedCount); + public implementationListIsEmpty() { + this.state.verifyImplementationListIsEmpty(this.negative); } public isValidBraceCompletionAtPosition(openingBrace: string) { @@ -3319,8 +3315,8 @@ namespace FourSlashInterface { this.state.verifyProjectInfo(expected); } - public allRangesAppearInImplementationList() { - this.state.verifyRangesInImplementationList(); + public allRangesAppearInImplementationList(markerName: string) { + this.state.verifyRangesInImplementationList(markerName); } } diff --git a/src/services/services.ts b/src/services/services.ts index 80cb181a643..53eddecee3f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1054,13 +1054,6 @@ namespace ts { moduleDir: string; } - // Internal interface used for tracking state in find all references when checking - // the inheritance hierarchy of property access expressions - interface SymbolInheritanceState { - symbol: Symbol; - cachedInheritanceResults: Map; - } - export interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; } @@ -5026,37 +5019,25 @@ namespace ts { // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { const result: ReferenceEntry[] = []; - getReferenceEntryForShorthandPropertyAssignment(node, typeChecker, result); + getReferenceEntriesForShorthandPropertyAssignment(node, typeChecker, result); return result.length > 0 ? result : undefined; } else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no // need to "Find all References" const symbol = typeChecker.getSymbolAtLocation(node); - if (symbol.valueDeclaration) { - return [getReferenceEntryFromNode(symbol.valueDeclaration)]; - } + return symbol.valueDeclaration && [getReferenceEntryFromNode(symbol.valueDeclaration)]; } else { - const entries: ImplementationLocation[] = []; // Perform "Find all References" and retrieve only those that are implementations - const result = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); + const referencedSymbols = getReferencedSymbolsForNode(node, program.getSourceFiles(), /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); - forEach(result, referencedSymbol => { - if (referencedSymbol.references) { - forEach(referencedSymbol.references, entry => { - entries.push({ - textSpan: entry.textSpan, - fileName: entry.fileName - }); - }); - } - }); - return entries; + return flatMap(referencedSymbols, symbol => + map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); } } - function getReferenceEntryForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker, result: ReferenceEntry[]): void { + function getReferenceEntriesForShorthandPropertyAssignment(node: Node, typeChecker: TypeChecker, result: ReferenceEntry[]): void { const refSymbol = typeChecker.getSymbolAtLocation(node); const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); @@ -5069,25 +5050,26 @@ namespace ts { } } - function isNameOfImplementation(node: Node): boolean { - const parent = node.parent; - - if (isDeclarationName(node)) { - if (isVariableLike(parent)) { - if (parent.kind === SyntaxKind.VariableDeclaration) { - const parentStatement = parent.parent && parent.parent.parent; - if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { - return true; - } + function isImplementation(node: Node): boolean { + if (!node) { + return false; + } + else if (isVariableLike(node)) { + if (node.initializer) { + return true; + } + else if (node.kind === SyntaxKind.VariableDeclaration) { + const parentStatement = getParentStatementOfVariableDeclaration(node); + if (parentStatement && hasModifier(parentStatement, ModifierFlags.Ambient)) { + return true; } - return !!parent.initializer; } - else if (isFunctionLike(parent)) { - return !!parent.body || hasModifier(parent, ModifierFlags.Ambient); - } - - switch (parent.kind) { - case SyntaxKind.PropertyAssignment: + } + else if (isFunctionLike(node)) { + return !!node.body || hasModifier(node, ModifierFlags.Ambient); + } + else { + switch (node.kind) { case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.EnumDeclaration: @@ -5095,12 +5077,12 @@ namespace ts { return true; } } - return false; } - function isTypeAssertionExpression(node: Node): node is TypeAssertion { - return node.kind === SyntaxKind.TypeAssertionExpression; + function getParentStatementOfVariableDeclaration(node: VariableDeclaration): VariableStatement { + return node.parent && node.parent.kind === SyntaxKind.VariableDeclarationList && node.parent.parent + && node.parent.parent.kind === SyntaxKind.VariableStatement && node.parent.parent; } function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { @@ -6197,24 +6179,8 @@ namespace ts { const start = findInComments ? container.getFullStart() : container.getStart(); const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd()); - // If we are just looking for implementations and this is a property access expression, we need to get the - // symbol of the local type of the symbol the property is being accessed on. This is because our search - // symbol may have a different parent symbol if the local type's symbol does not declare the property - // being accessed (i.e. it is declared in some parent class or interface) - let parents: Symbol[]; - const cache: Map = createMap(); - - if (implementations && isRightSideOfPropertyAccess(searchLocation)) { - const localParentType = typeChecker.getTypeAtLocation((searchLocation.parent).expression); - if (localParentType) { - if (localParentType.symbol && localParentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { - parents = [localParentType.symbol]; - } - else if (localParentType.getFlags() & TypeFlags.UnionOrIntersection) { - parents = getSymbolsForComponentTypes(localParentType); - } - } - } + const parents = getParentSymbolsOfPropertyAccess(); + const inheritsFromCache: Map = createMap(); if (possiblePositions.length) { // Build the set of symbols to search for, initially it has only the current symbol @@ -6257,7 +6223,7 @@ namespace ts { const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, - /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, cache); + /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache); if (relatedSymbol) { addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); @@ -6279,6 +6245,32 @@ namespace ts { } return; + /* If we are just looking for implementations and this is a property access expression, we need to get the + * symbol of the local type of the symbol the property is being accessed on. This is because our search + * symbol may have a different parent symbol if the local type's symbol does not declare the property + * being accessed (i.e. it is declared in some parent class or interface) + */ + function getParentSymbolsOfPropertyAccess(): Symbol[] | undefined { + if (implementations) { + const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(searchLocation); + if (propertyAccessExpression) { + const localParentType = typeChecker.getTypeAtLocation(propertyAccessExpression.expression); + if (localParentType) { + if (localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { + return [localParentType.symbol]; + } + else if (localParentType.flags & TypeFlags.UnionOrIntersection) { + return getSymbolsForClassAndInterfaceComponents(localParentType); + } + } + } + } + } + + function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression { + return isRightSideOfPropertyAccess(node) && node.parent; + } + /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ function findAdditionalConstructorReferences(referenceSymbol: Symbol, referenceLocation: Node): void { Debug.assert(isClassLike(searchSymbol.valueDeclaration)); @@ -6387,19 +6379,19 @@ namespace ts { function getImplementationReferenceEntryForNode(refNode: Node, result: ReferenceEntry[]): void { // Check if we found a function/propertyAssignment/method with an implementation or initializer - if (isNameOfImplementation(refNode)) { + if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { result.push(getReferenceEntryFromNode(refNode.parent)); } else if (refNode.kind === SyntaxKind.Identifier) { if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { // Go ahead and dereference the shorthand assignment by going to its definition - getReferenceEntryForShorthandPropertyAssignment(refNode, typeChecker, result); + getReferenceEntriesForShorthandPropertyAssignment(refNode, typeChecker, result); } // Check if the node is within an extends or implements clause - const containingHeritageClause = getContainingClassHeritageClause(refNode); - if (containingHeritageClause) { - result.push(getReferenceEntryFromNode(containingHeritageClause.parent)); + const containingClass = getContainingClassIfInHeritageClause(refNode); + if (containingClass) { + result.push(getReferenceEntryFromNode(containingClass)); return; } @@ -6410,14 +6402,19 @@ namespace ts { if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { maybeAdd(getReferenceEntryFromNode(parent.initializer)); } - else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body && parent.body.kind === SyntaxKind.Block) { - forEachReturnStatement(parent.body, (returnStatement) => { - if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); - } - }); + else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) { + if (parent.body.kind === SyntaxKind.Block) { + forEachReturnStatement(parent.body, returnStatement => { + if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { + maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); + } + }); + } + else if (isImplementationExpression(parent.body)) { + maybeAdd(getReferenceEntryFromNode(parent.body)); + } } - else if (isTypeAssertionExpression(parent) && isImplementationExpression(parent.expression)) { + else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { maybeAdd(getReferenceEntryFromNode(parent.expression)); } } @@ -6435,13 +6432,13 @@ namespace ts { } } - function getSymbolsForComponentTypes(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { + function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { for (const componentType of type.types) { if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { result.push(componentType.symbol); } if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { - getSymbolsForComponentTypes(componentType, result); + getSymbolsForClassAndInterfaceComponents(componentType, result); } } return result; @@ -6460,23 +6457,23 @@ namespace ts { return topLevelTypeReference; } - function getContainingClassHeritageClause(node: Node): HeritageClause { - if (node) { + function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration { + if (node && node.parent) { if (node.kind === SyntaxKind.ExpressionWithTypeArguments && node.parent.kind === SyntaxKind.HeritageClause && isClassLike(node.parent.parent)) { - return node.parent; + return node.parent.parent; } else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { - return getContainingClassHeritageClause(node.parent); + return getContainingClassIfInHeritageClause(node.parent); } } return undefined; } /** - * Returns true if this is an expression that could be used to implement an interface. + * Returns true if this is an expression that can be considered an implementation */ function isImplementationExpression(node: Expression): boolean { // Unwrap parentheses @@ -6517,6 +6514,7 @@ namespace ts { return cachedResults[key]; } + // Set the key so that we don't infinitely recurse cachedResults[key] = false; const inherits = forEach(symbol.getDeclarations(), (declaration) => { @@ -6910,7 +6908,7 @@ namespace ts { } } - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[], cache: Map): Symbol { + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[] | undefined, cache: Map): Symbol { if (contains(searchSymbols, referenceSymbol)) { // If we are searching for constructor uses, they must be 'new' expressions. return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) && referenceSymbol; @@ -6966,6 +6964,7 @@ namespace ts { // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + // Parents will only be defined if implementations is true if (parents) { if (!forEach(parents, parent => inheritsFrom(rootSymbol.parent, parent, cache))) { return undefined; diff --git a/src/services/shims.ts b/src/services/shims.ts index 8771e014695..deab2addc87 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -179,7 +179,7 @@ namespace ts { /** * Returns a JSON-encoded value of the type: - * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] + * { fileName: string; textSpan: { start: number; length: number}; }[] */ getImplementationAtPosition(fileName: string, position: number): string; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b1adba20c52..e484a1cd782 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -110,7 +110,7 @@ declare namespace FourSlashInterface { bof(): void; eof(): void; type(definitionIndex?: number): void; - implementation(implementationIndex?: number): void; + implementation(): void; position(position: number, fileIndex?: number): any; position(position: number, fileName?: string): any; file(index: number, content?: string, scriptKindName?: string): any; @@ -134,7 +134,7 @@ declare namespace FourSlashInterface { quickInfoIs(expectedText?: string, expectedDocumentation?: string): void; quickInfoExists(): void; typeDefinitionCountIs(expectedCount: number): void; - implementationCountIs(expectedCount: number): void; + implementationListIsEmpty(): void; isValidBraceCompletionAtPosition(openingBrace?: string): void; } class verify extends verifyNegatable { @@ -242,7 +242,7 @@ declare namespace FourSlashInterface { getSyntacticDiagnostics(expected: string): void; getSemanticDiagnostics(expected: string): void; ProjectInfo(expected: string[]): void; - allRangesAppearInImplementationList(): void; + allRangesAppearInImplementationList(markerName: string): void; } class edit { backspace(count?: number): void; diff --git a/tests/cases/fourslash/goToImplementationClassMethod_00.ts b/tests/cases/fourslash/goToImplementationClassMethod_00.ts index 465db091d32..6fc8d9bf7cc 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_00.ts @@ -8,5 +8,4 @@ //// //// new Bar().hel/*reference*/lo; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationClassMethod_01.ts b/tests/cases/fourslash/goToImplementationClassMethod_01.ts index 8b1cb3e762d..7f59376a6ae 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_01.ts @@ -14,8 +14,5 @@ //// x.he/*reference*/llo(); //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_00.ts b/tests/cases/fourslash/goToImplementationEnum_00.ts index 3a93542f806..81e72b871a2 100644 --- a/tests/cases/fourslash/goToImplementationEnum_00.ts +++ b/tests/cases/fourslash/goToImplementationEnum_00.ts @@ -9,5 +9,4 @@ //// //// Foo.Fo/*reference*/o1; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationEnum_01.ts b/tests/cases/fourslash/goToImplementationEnum_01.ts index 2e7203f3c8f..43273b6b03a 100644 --- a/tests/cases/fourslash/goToImplementationEnum_01.ts +++ b/tests/cases/fourslash/goToImplementationEnum_01.ts @@ -9,5 +9,4 @@ //// //// Fo/*reference*/o; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts index ca5498c3492..38afd0cfb3d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts @@ -21,8 +21,5 @@ //// constructor(public f: Foo = { [|hello() {/**3*/}|] } ) {} //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts index 5f5ba64338b..8bd328bcb54 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts @@ -18,8 +18,5 @@ //// //// whatever(new Bar()); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts index f5b1f1eea93..82dceaad91c 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts @@ -18,8 +18,5 @@ //// a.he/*function_call*/llo(); //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts index cc22956bb05..8826cc1eab4 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts @@ -21,5 +21,4 @@ //// new Bar().hel/*function_call*/lo(); //// new Bar()["hello"](); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts index 32f5ff41484..a9b825c717f 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts @@ -22,5 +22,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts index 5e8bd76a072..b051e16a929 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts @@ -34,5 +34,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts index b7f275e6c07..b340270096d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts @@ -45,5 +45,4 @@ //// x.he/*function_call*/llo() //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts index e3db4b5157d..d2038f99efd 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts @@ -19,5 +19,4 @@ //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts index 922ea026888..84c57ec2bce 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts @@ -27,8 +27,5 @@ //// hello() {} //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); - -goTo.marker("element_access"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); +verify.allRangesAppearInImplementationList("element_access"); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts index 76d4e750ad9..0604d2511f2 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts @@ -44,6 +44,5 @@ //// } for (var i = 0; i < 2; i++) { - goTo.marker("function_call" + i); - verify.allRangesAppearInImplementationList(); + verify.allRangesAppearInImplementationList("function_call" + i); } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts index 7d948006fb3..9528aa409b4 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts @@ -8,5 +8,5 @@ //// //// var x = { [|hello: () => {}|] }; //// var y = (((({ [|hello: () => {}|] })))); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts index 43b59d021d3..70e49c10b45 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts @@ -19,5 +19,4 @@ //// constructor(public f: Foo = { [|hello: 7|] } ) {} //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts index 2725a5ab9d4..14b80362917 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts @@ -12,5 +12,4 @@ //// foo.he/*reference*/llo; //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_00.ts b/tests/cases/fourslash/goToImplementationInterface_00.ts index fc9f6aace07..8fc36b4bab5 100644 --- a/tests/cases/fourslash/goToImplementationInterface_00.ts +++ b/tests/cases/fourslash/goToImplementationInterface_00.ts @@ -22,6 +22,4 @@ //// constructor(public f: Foo = [|{ hello() {/**3*/} }|] ) {} //// } - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_01.ts b/tests/cases/fourslash/goToImplementationInterface_01.ts index 6d9d5c97507..62d01da6ca8 100644 --- a/tests/cases/fourslash/goToImplementationInterface_01.ts +++ b/tests/cases/fourslash/goToImplementationInterface_01.ts @@ -21,5 +21,4 @@ //// var y: SuperBar = new SuperBar(); //// var z: AbstractBar = new NotAbstractBar(); -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_02.ts b/tests/cases/fourslash/goToImplementationInterface_02.ts index af7f188ffa4..27f29465a9a 100644 --- a/tests/cases/fourslash/goToImplementationInterface_02.ts +++ b/tests/cases/fourslash/goToImplementationInterface_02.ts @@ -17,11 +17,12 @@ //// }|]; //// } //// +//// let createFoo2 = (): Foo => [|({hello() {}})|]; +//// //// function createFooLike() { //// return { //// hello() {} //// }; //// } -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_03.ts b/tests/cases/fourslash/goToImplementationInterface_03.ts index b198269d498..1c63852dafc 100644 --- a/tests/cases/fourslash/goToImplementationInterface_03.ts +++ b/tests/cases/fourslash/goToImplementationInterface_03.ts @@ -6,5 +6,4 @@ //// //// var x = [|{ hello: () => {} }|]; -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_04.ts b/tests/cases/fourslash/goToImplementationInterface_04.ts index 3989c194363..febc511388d 100644 --- a/tests/cases/fourslash/goToImplementationInterface_04.ts +++ b/tests/cases/fourslash/goToImplementationInterface_04.ts @@ -17,6 +17,4 @@ //// constructor(public f: Foo = [|function(a) {}|] ) {} //// } - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_05.ts b/tests/cases/fourslash/goToImplementationInterface_05.ts index d0f87c6d6d4..3b31b89b528 100644 --- a/tests/cases/fourslash/goToImplementationInterface_05.ts +++ b/tests/cases/fourslash/goToImplementationInterface_05.ts @@ -9,6 +9,4 @@ //// let bar2 = [|function(a) {}|]; //// - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_06.ts b/tests/cases/fourslash/goToImplementationInterface_06.ts index 7ba2ebfc023..15f52132868 100644 --- a/tests/cases/fourslash/goToImplementationInterface_06.ts +++ b/tests/cases/fourslash/goToImplementationInterface_06.ts @@ -11,6 +11,4 @@ //// let x: Foo = [|class { constructor (a: number) {} }|]; //// let y = [|class { constructor (a: number) {} }|]; - -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_07.ts b/tests/cases/fourslash/goToImplementationInterface_07.ts index 6a8665ec213..6d874b3dc76 100644 --- a/tests/cases/fourslash/goToImplementationInterface_07.ts +++ b/tests/cases/fourslash/goToImplementationInterface_07.ts @@ -25,5 +25,4 @@ //// return true; //// } -goTo.marker("interface_definition"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterface_08.ts b/tests/cases/fourslash/goToImplementationInterface_08.ts new file mode 100644 index 00000000000..652cfe46246 --- /dev/null +++ b/tests/cases/fourslash/goToImplementationInterface_08.ts @@ -0,0 +1,21 @@ +/// + +// Should not hang on inheritance loops + +//// interface Base { +//// hello (): void; +//// } +//// +//// interface A extends Base {} +//// interface B extends C, A {} +//// interface C extends B, A {} +//// +//// class X implements B { +//// [|hello() {}|] +//// } +//// +//// function someFunction(d : A) { +//// d.he/*function_call*/llo(); +//// } + +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInvalid.ts b/tests/cases/fourslash/goToImplementationInvalid.ts index a9739c9fe12..52b2773342e 100644 --- a/tests/cases/fourslash/goToImplementationInvalid.ts +++ b/tests/cases/fourslash/goToImplementationInvalid.ts @@ -8,5 +8,5 @@ for(var i = 0; i < 3; i++) { goTo.marker("" + i); - verify.implementationCountIs(0); + verify.implementationListIsEmpty(); } \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_00.ts b/tests/cases/fourslash/goToImplementationLocal_00.ts index 0d0ba9001b7..b97fadfcb02 100644 --- a/tests/cases/fourslash/goToImplementationLocal_00.ts +++ b/tests/cases/fourslash/goToImplementationLocal_00.ts @@ -5,5 +5,4 @@ //// he/*function_call*/llo(); //// [|function hello() {}|] -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_01.ts b/tests/cases/fourslash/goToImplementationLocal_01.ts index d2ccb976e95..0bda3418354 100644 --- a/tests/cases/fourslash/goToImplementationLocal_01.ts +++ b/tests/cases/fourslash/goToImplementationLocal_01.ts @@ -5,5 +5,4 @@ //// const [|hello = function() {}|]; //// he/*function_call*/llo(); -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_02.ts b/tests/cases/fourslash/goToImplementationLocal_02.ts index 47097652d81..62bb8a71a10 100644 --- a/tests/cases/fourslash/goToImplementationLocal_02.ts +++ b/tests/cases/fourslash/goToImplementationLocal_02.ts @@ -4,5 +4,5 @@ //// //// x.he/*function_call*/llo(); //// -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_03.ts b/tests/cases/fourslash/goToImplementationLocal_03.ts index 46ad28a3e1d..d3f25ea29dc 100644 --- a/tests/cases/fourslash/goToImplementationLocal_03.ts +++ b/tests/cases/fourslash/goToImplementationLocal_03.ts @@ -8,5 +8,5 @@ //// //// hello = {}; //// -goTo.marker("local_var"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_04.ts b/tests/cases/fourslash/goToImplementationLocal_04.ts index 3452749bdcf..9de9dcd0a9f 100644 --- a/tests/cases/fourslash/goToImplementationLocal_04.ts +++ b/tests/cases/fourslash/goToImplementationLocal_04.ts @@ -6,5 +6,5 @@ //// //// hello(); //// -goTo.marker("local_var"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_05.ts b/tests/cases/fourslash/goToImplementationLocal_05.ts index e58343d2505..969f4c25fc7 100644 --- a/tests/cases/fourslash/goToImplementationLocal_05.ts +++ b/tests/cases/fourslash/goToImplementationLocal_05.ts @@ -8,5 +8,5 @@ //// //// var [|someVar = new Bar()|]; //// someVa/*reference*/r.hello(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_06.ts b/tests/cases/fourslash/goToImplementationLocal_06.ts index 74ef1d77866..acdbaffc36f 100644 --- a/tests/cases/fourslash/goToImplementationLocal_06.ts +++ b/tests/cases/fourslash/goToImplementationLocal_06.ts @@ -4,5 +4,5 @@ //// declare var [|someVar: string|]; //// someVa/*reference*/r -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_07.ts b/tests/cases/fourslash/goToImplementationLocal_07.ts index 53159a45810..3556c25abc0 100644 --- a/tests/cases/fourslash/goToImplementationLocal_07.ts +++ b/tests/cases/fourslash/goToImplementationLocal_07.ts @@ -4,5 +4,5 @@ //// [|declare function someFunction(): () => void;|] //// someFun/*reference*/ction(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationLocal_08.ts b/tests/cases/fourslash/goToImplementationLocal_08.ts index 53159a45810..3556c25abc0 100644 --- a/tests/cases/fourslash/goToImplementationLocal_08.ts +++ b/tests/cases/fourslash/goToImplementationLocal_08.ts @@ -4,5 +4,5 @@ //// [|declare function someFunction(): () => void;|] //// someFun/*reference*/ction(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file + +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_01.ts b/tests/cases/fourslash/goToImplementationNamespace_01.ts index ea24336be7e..b2e267d5378 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_01.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_01.ts @@ -2,11 +2,10 @@ // Should handle property access expressions on namespaces -//// namespace Foo { -//// [|export function hello() {}|] -//// } -//// +//// namespace Foo { +//// [|export function hello() {}|] +//// } +//// //// Foo.hell/*reference*/o(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_02.ts b/tests/cases/fourslash/goToImplementationNamespace_02.ts index c4388df7e8a..2d2ae960a99 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_02.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_02.ts @@ -2,11 +2,10 @@ // Should handle property access expressions on namespaces -//// module Foo { -//// [|export function hello() {}|] -//// } -//// +//// module Foo { +//// [|export function hello() {}|] +//// } +//// //// Foo.hell/*reference*/o(); -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationNamespace_03.ts b/tests/cases/fourslash/goToImplementationNamespace_03.ts index 38aeb47feae..751d182ec00 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_03.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_03.ts @@ -24,5 +24,4 @@ //// //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationNamespace_04.ts b/tests/cases/fourslash/goToImplementationNamespace_04.ts index fc64275d906..ac0b85e43fe 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_04.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_04.ts @@ -24,5 +24,4 @@ //// //// } -goTo.marker("reference"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts index 68b4898c6f7..f5e52d90b1c 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_06.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_06.ts @@ -9,5 +9,4 @@ //// //// let x: typeof Foo = [|{ hello() {} }|]; -goTo.marker("declaration"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("declaration"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts index abb0aad0602..fb4763619a4 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts @@ -44,5 +44,4 @@ //// //// createBarUsingClassDeclaration().Fo/*reference*/o; -goTo.marker("reference"); -verify.allRangesAppearInImplementationList();; \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts index 8db6cbce5de..a27480c8272 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts @@ -18,5 +18,4 @@ //// x.h/*function_call*/ello(); //// } -goTo.marker("function_call"); -verify.allRangesAppearInImplementationList(); +verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationSuper_00.ts b/tests/cases/fourslash/goToImplementationSuper_00.ts index b7def58ca59..53377bdcdb0 100644 --- a/tests/cases/fourslash/goToImplementationSuper_00.ts +++ b/tests/cases/fourslash/goToImplementationSuper_00.ts @@ -12,5 +12,4 @@ //// } //// } -goTo.marker("super_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("super_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationSuper_01.ts b/tests/cases/fourslash/goToImplementationSuper_01.ts index 11ba0719e5d..fffa7caf716 100644 --- a/tests/cases/fourslash/goToImplementationSuper_01.ts +++ b/tests/cases/fourslash/goToImplementationSuper_01.ts @@ -12,5 +12,4 @@ //// } //// } -goTo.marker("super_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("super_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_00.ts b/tests/cases/fourslash/goToImplementationThis_00.ts index 0e4a0ff9849..19212c9a77a 100644 --- a/tests/cases/fourslash/goToImplementationThis_00.ts +++ b/tests/cases/fourslash/goToImplementationThis_00.ts @@ -10,5 +10,4 @@ //// whatever() {} //// }|] -goTo.marker("this_call"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_call"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationThis_01.ts b/tests/cases/fourslash/goToImplementationThis_01.ts index 001ebc08b9f..6761c6ec6c9 100644 --- a/tests/cases/fourslash/goToImplementationThis_01.ts +++ b/tests/cases/fourslash/goToImplementationThis_01.ts @@ -8,5 +8,4 @@ //// } //// }|] -goTo.marker("this_type"); -verify.allRangesAppearInImplementationList(); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_type"); \ No newline at end of file