From efc1b7df082e8c2b074c84468fc5b8a30d82d738 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 2 Jul 2018 19:25:27 -0700 Subject: [PATCH] More thoroughly test navigateTo (#25239) * More thoroughly test navigateTo * Fix #25233 and #25237 * Update API (#24966) --- src/compiler/utilities.ts | 15 +-- src/harness/client.ts | 6 +- src/harness/fourslash.ts | 102 ++++++------------ src/server/protocol.ts | 4 +- src/server/session.ts | 5 +- src/services/navigateTo.ts | 33 +++--- src/services/navigationBar.ts | 2 +- src/services/patternMatcher.ts | 2 - src/services/services.ts | 6 +- src/services/types.ts | 4 +- src/services/utilities.ts | 3 +- .../unittests/tsserverProjectSystem.ts | 4 +- .../reference/api/tsserverlibrary.d.ts | 10 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../cases/fourslash/declarationExpressions.ts | 39 +++---- tests/cases/fourslash/declareFunction.ts | 6 +- tests/cases/fourslash/fourslash.ts | 19 +++- .../incorrectJsDocObjectLiteralType.ts | 18 +++- tests/cases/fourslash/navigateItemsConst.ts | 21 ++-- tests/cases/fourslash/navigateItemsExports.ts | 33 +++--- tests/cases/fourslash/navigateItemsImports.ts | 45 ++++---- tests/cases/fourslash/navigateItemsLet.ts | 20 ++-- tests/cases/fourslash/navigateToIIFE.ts | 31 +++--- tests/cases/fourslash/navigateToImport.ts | 18 ++-- tests/cases/fourslash/navigateToQuoted.ts | 24 ++++- .../fourslash/navigateToSingleFileResults.ts | 30 ++++-- .../fourslash/navigateToSymbolIterator.ts | 9 +- .../navigationBarNamespaceImportWithNoName.ts | 2 + .../navigationItemsComputedProperties.ts | 30 +++--- .../fourslash/navigationItemsExactMatch.ts | 41 ++++--- .../fourslash/navigationItemsExactMatch2.ts | 62 +++++++---- ...navigationItemsInConstructorsExactMatch.ts | 19 ++-- .../fourslash/navigationItemsOverloads1.ts | 35 ++++-- .../fourslash/navigationItemsOverloads2.ts | 10 +- .../navigationItemsOverloadsBroken1.ts | 30 ++++-- .../navigationItemsOverloadsBroken2.ts | 35 ++++-- .../fourslash/navigationItemsPrefixMatch.ts | 44 ++++---- .../fourslash/navigationItemsPrefixMatch2.ts | 56 ++++++---- ...avigationItemsSpecialPropertyAssignment.ts | 53 ++++++--- .../navigationItemsSubStringMatch.ts | 27 +++-- .../navigationItemsSubStringMatch2.ts | 76 ++++++++----- tests/cases/fourslash/quickInfoMeaning.ts | 41 ++++--- tests/cases/fourslash/server/navto01.ts | 30 +++--- .../fourslash/shims-pp/getNavigateToItems.ts | 33 +++--- .../fourslash/shims/getNavigateToItems.ts | 33 +++--- 45 files changed, 658 insertions(+), 510 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a1c6d5137b2..ca28df4dab0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4866,14 +4866,9 @@ namespace ts { return !!(node as NamedDeclaration).name; // A 'name' property should always be a DeclarationName. } - export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined { + /** @internal */ + export function getNonAssignedNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined { switch (declaration.kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - if (!(declaration as ClassExpression | FunctionExpression).name) { - return getAssignedName(declaration); - } - break; case SyntaxKind.Identifier: return declaration as Identifier; case SyntaxKind.JSDocPropertyTag: @@ -4906,6 +4901,12 @@ namespace ts { return (declaration as NamedDeclaration).name; } + export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined { + if (declaration === undefined) return undefined; + return getNonAssignedNameOfDeclaration(declaration) || + (isFunctionExpression(declaration) || isClassExpression(declaration) ? getAssignedName(declaration) : undefined); + } + function getAssignedName(node: Node): DeclarationName | undefined { if (!node.parent) { return undefined; diff --git a/src/harness/client.ts b/src/harness/client.ts index 4cd29266027..20748a9c54c 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -224,9 +224,9 @@ namespace ts.server { containerName: entry.containerName || "", containerKind: entry.containerKind || ScriptElementKind.unknown, kind: entry.kind, - kindModifiers: entry.kindModifiers!, // TODO: GH#18217 - matchKind: entry.matchKind!, // TODO: GH#18217 - isCaseSensitive: entry.isCaseSensitive!, // TODO: GH#18217 + kindModifiers: entry.kindModifiers || "", + matchKind: entry.matchKind as keyof typeof PatternMatchKind, + isCaseSensitive: entry.isCaseSensitive, fileName: entry.file, textSpan: this.decodeSpan(entry), })); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f2ff965d4b2..46bd961e9f8 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2775,57 +2775,20 @@ Actual: ${stringify(fullActual)}`); } } - /* - Check number of navigationItems which match both searchValue and matchKind, - if a filename is passed in, limit the results to that file. - Report an error if expected value and actual value do not match. - */ - public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string, fileName?: string) { - const items = this.languageService.getNavigateToItems(searchValue, /*maxResultCount*/ undefined, fileName); - let actual = 0; - - // Count only the match that match the same MatchKind - for (const item of items) { - if (!matchKind || item.matchKind === matchKind) { - actual++; - } - } - - if (expected !== actual) { - this.raiseError(`verifyNavigationItemsCount failed - found: ${actual} navigation items, expected: ${expected}.`); - } - } - - /* - Verify that returned navigationItems from getNavigateToItems have matched searchValue, matchKind, and kind. - Report an error if getNavigateToItems does not find any matched searchValue. - */ - public verifyNavigationItemsListContains( - name: string, - kind: string, - searchValue: string, - matchKind: string, - fileName?: string, - parentName?: string) { - const items = this.languageService.getNavigateToItems(searchValue); - - if (!items || items.length === 0) { - this.raiseError("verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one."); - } - - for (const item of items) { - if (item && item.name === name && item.kind === kind && - (matchKind === undefined || item.matchKind === matchKind) && - (fileName === undefined || item.fileName === fileName) && - (parentName === undefined || item.containerName === parentName)) { - return; - } - } - - // if there was an explicit match kind specified, then it should be validated. - if (matchKind !== undefined) { - const missingItem = { name, kind, searchValue, matchKind, fileName, parentName }; - this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(items)})`); + public verifyNavigateTo(options: ReadonlyArray): void { + for (const { pattern, expected, fileName } of options) { + const items = this.languageService.getNavigateToItems(pattern, /*maxResultCount*/ undefined, fileName); + this.assertObjectsEqual(items, expected.map((e): ts.NavigateToItem => ({ + name: e.name, + kind: e.kind, + kindModifiers: e.kindModifiers || "", + matchKind: e.matchKind || "exact", + isCaseSensitive: e.isCaseSensitive === undefined ? true : e.isCaseSensitive, + fileName: e.range.fileName, + textSpan: ts.createTextSpanFromRange(e.range), + containerName: e.containerName || "", + containerKind: e.containerKind || ts.ScriptElementKind.unknown, + }))); } } @@ -4361,24 +4324,8 @@ namespace FourSlashInterface { this.state.verifyNavigationTree(json, options); } - public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) { - this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName); - } - - public navigationItemsListContains( - name: string, - kind: string, - searchValue: string, - matchKind: string, - fileName?: string, - parentName?: string) { - this.state.verifyNavigationItemsListContains( - name, - kind, - searchValue, - matchKind, - fileName, - parentName); + public navigateTo(...options: VerifyNavigateToOptions[]): void { + this.state.verifyNavigateTo(options); } public occurrencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean) { @@ -4812,6 +4759,23 @@ namespace FourSlashInterface { readonly tags?: ReadonlyArray; } + export interface VerifyNavigateToOptions { + readonly pattern: string; + readonly fileName?: string; + readonly expected: ReadonlyArray; + } + + export interface ExpectedNavigateToItem { + readonly name: string; + readonly kind: ts.ScriptElementKind; + readonly kindModifiers?: string; + readonly matchKind?: keyof typeof ts.PatternMatchKind; + readonly isCaseSensitive?: boolean; + readonly range: FourSlash.Range; + readonly containerName?: string; + readonly containerKind?: ts.ScriptElementKind; + } + export type ArrayOrSingle = T | ReadonlyArray; export interface VerifyCompletionListContainsOptions extends ts.UserPreferences { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 23894a0f67d..5eeacee70ea 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2458,12 +2458,12 @@ namespace ts.server.protocol { /** * exact, substring, or prefix. */ - matchKind?: string; + matchKind: string; /** * If this was a case sensitive or insensitive match. */ - isCaseSensitive?: boolean; + isCaseSensitive: boolean; /** * Optional modifiers for the kind (such as 'public'). diff --git a/src/server/session.ts b/src/server/session.ts index 972743d3921..42482ec1f45 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1591,6 +1591,8 @@ namespace ts.server { const bakedItem: protocol.NavtoItem = { name: navItem.name, kind: navItem.kind, + isCaseSensitive: navItem.isCaseSensitive, + matchKind: navItem.matchKind, file: navItem.fileName, start: scriptInfo.positionToLineOffset(navItem.textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)) @@ -1598,9 +1600,6 @@ namespace ts.server { if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; } - if (navItem.matchKind !== "none") { - bakedItem.matchKind = navItem.matchKind; - } if (navItem.containerName && (navItem.containerName.length > 0)) { bakedItem.containerName = navItem.containerName; } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index dc03c736f3c..38ac57255f4 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -1,17 +1,17 @@ /* @internal */ namespace ts.NavigateTo { interface RawNavigateToItem { - name: string; - fileName: string; - matchKind: PatternMatchKind; - isCaseSensitive: boolean; - declaration: Declaration; + readonly name: string; + readonly fileName: string; + readonly matchKind: PatternMatchKind; + readonly isCaseSensitive: boolean; + readonly declaration: Declaration; } export function getNavigateToItems(sourceFiles: ReadonlyArray, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number | undefined, excludeDtsFiles: boolean): NavigateToItem[] { const patternMatcher = createPatternMatcher(searchValue); if (!patternMatcher) return emptyArray; - let rawItems: RawNavigateToItem[] = []; + const rawItems: RawNavigateToItem[] = []; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] for (const sourceFile of sourceFiles) { @@ -27,10 +27,7 @@ namespace ts.NavigateTo { } rawItems.sort(compareNavigateToItems); - if (maxResultCount !== undefined) { - rawItems = rawItems.slice(0, maxResultCount); - } - return rawItems.map(createNavigateToItem); + return (maxResultCount === undefined ? rawItems : rawItems.slice(0, maxResultCount)).map(createNavigateToItem); } function getItemsFromNamedDeclaration(patternMatcher: PatternMatcher, name: string, declarations: ReadonlyArray, checker: TypeChecker, fileName: string, rawItems: Push): void { @@ -45,13 +42,13 @@ namespace ts.NavigateTo { if (!shouldKeepItem(declaration, checker)) continue; if (patternMatcher.patternContainsDots) { - const fullMatch = patternMatcher.getFullMatch(getContainers(declaration)!, name); // TODO: GH#18217 + // If the pattern has dots in it, then also see if the declaration container matches as well. + const fullMatch = patternMatcher.getFullMatch(getContainers(declaration), name); if (fullMatch) { rawItems.push({ name, fileName, matchKind: fullMatch.kind, isCaseSensitive: fullMatch.isCaseSensitive, declaration }); } } else { - // If the pattern has dots in it, then also see if the declaration container matches as well. rawItems.push({ name, fileName, matchKind: match.kind, isCaseSensitive: match.isCaseSensitive, declaration }); } } @@ -62,7 +59,7 @@ namespace ts.NavigateTo { case SyntaxKind.ImportClause: case SyntaxKind.ImportSpecifier: case SyntaxKind.ImportEqualsDeclaration: - const importer = checker.getSymbolAtLocation((declaration as ImportClause | ImportSpecifier | ImportEqualsDeclaration).name!)!; + const importer = checker.getSymbolAtLocation((declaration as ImportClause | ImportSpecifier | ImportEqualsDeclaration).name!)!; // TODO: GH#18217 const imported = checker.getAliasedSymbol(importer); return importer.escapedName !== imported.escapedName; default: @@ -107,14 +104,14 @@ namespace ts.NavigateTo { return false; } - function getContainers(declaration: Declaration): string[] | undefined { + function getContainers(declaration: Declaration): ReadonlyArray { const containers: string[] = []; // First, if we started with a computed property name, then add all but the last // portion into the container array. const name = getNameOfDeclaration(declaration); if (name && name.kind === SyntaxKind.ComputedPropertyName && !tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) { - return undefined; + return emptyArray; } // Now, walk up our containers, adding all their names to the container array. @@ -122,7 +119,7 @@ namespace ts.NavigateTo { while (container) { if (!tryAddSingleDeclarationName(container, containers)) { - return undefined; + return emptyArray; } container = getContainerNode(container); @@ -145,13 +142,13 @@ namespace ts.NavigateTo { name: rawItem.name, kind: getNodeKind(declaration), kindModifiers: getNodeModifiers(declaration), - matchKind: PatternMatchKind[rawItem.matchKind], + matchKind: PatternMatchKind[rawItem.matchKind] as keyof typeof PatternMatchKind, isCaseSensitive: rawItem.isCaseSensitive, fileName: rawItem.fileName, textSpan: createTextSpanFromNode(declaration), // TODO(jfreeman): What should be the containerName when the container has a computed name? containerName: containerName ? (containerName).text : "", - containerKind: containerName ? getNodeKind(container!) : ScriptElementKind.unknown // TODO: GH#18217 Just use `container ? ...` + containerKind: containerName ? getNodeKind(container!) : ScriptElementKind.unknown, // TODO: GH#18217 Just use `container ? ...` }; } } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index d97004b80c5..2f928f52c7b 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -188,7 +188,7 @@ namespace ts.NavigationBar { // Handle default import case e.g.: // import d from "mod"; if (importClause.name) { - addLeafNode(importClause); + addLeafNode(importClause.name); } // Handle named bindings in imports e.g.: diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index 1b71eee0eaf..f81900e28e7 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -124,8 +124,6 @@ namespace ts { return undefined; } - candidateContainers = candidateContainers || []; - // -1 because the last part was checked against the name, and only the rest // of the parts are checked against the container. if (dotSeparatedSegments.length - 1 > candidateContainers.length) { diff --git a/src/services/services.ts b/src/services/services.ts index b2a2fdaaae2..03bb26d30e5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -633,7 +633,7 @@ namespace ts { private computeNamedDeclarations(): Map { const result = createMultiMap(); - forEachChild(this, visit); + this.forEachChild(visit); return result; @@ -653,7 +653,7 @@ namespace ts { } function getDeclarationName(declaration: Declaration) { - const name = getNameOfDeclaration(declaration); + const name = getNonAssignedNameOfDeclaration(declaration); return name && (isComputedPropertyName(name) && isPropertyAccessExpression(name.expression) ? name.expression.name.text : isPropertyName(name) ? getNameFromPropertyName(name) : undefined); } @@ -742,7 +742,7 @@ namespace ts { // Handle default import case e.g.: // import d from "mod"; if (importClause.name) { - addDeclaration(importClause); + addDeclaration(importClause.name); } // Handle named bindings in imports e.g.: diff --git a/src/services/types.ts b/src/services/types.ts index be897f20cd4..0475cfd9770 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -78,7 +78,7 @@ namespace ts { /* @internal */ scriptSnapshot: IScriptSnapshot | undefined; /* @internal */ nameTable: UnderscoreEscapedMap | undefined; - /* @internal */ getNamedDeclarations(): Map; + /* @internal */ getNamedDeclarations(): Map>; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineEndOfPosition(pos: number): number; @@ -599,7 +599,7 @@ namespace ts { name: string; kind: ScriptElementKind; kindModifiers: string; - matchKind: string; // TODO: keyof typeof PatternMatchKind; (https://github.com/Microsoft/TypeScript/issues/15102) + matchKind: "exact" | "prefix" | "substring" | "camelCase"; isCaseSensitive: boolean; fileName: string; textSpan: TextSpan; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a8c79ee8620..7a4712e15cd 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -347,7 +347,6 @@ namespace ts { case SyntaxKind.Parameter: return hasModifier(node, ModifierFlags.ParameterPropertyModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement; case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportClause: case SyntaxKind.ExportSpecifier: case SyntaxKind.NamespaceImport: return ScriptElementKind.alias; @@ -375,6 +374,8 @@ namespace ts { return ScriptElementKind.unknown; } } + case SyntaxKind.Identifier: + return isImportClause(node.parent) ? ScriptElementKind.alias : ScriptElementKind.unknown; default: return ScriptElementKind.unknown; } diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index 44064f15c5d..b65c59dbe8e 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -9010,7 +9010,7 @@ export function Test2() { const navtoRequest = makeSessionRequest(CommandNames.Navto, { file: bTs.path, searchValue: "fn" }); const navtoResponse = session.executeCommand(navtoRequest).response as protocol.NavtoResponse["body"]; - assert.deepEqual(navtoResponse, [ + assert.deepEqual | undefined>(navtoResponse, [ // TODO: First result should be from a.ts, not a.d.ts { file: "/a/bin/a.d.ts", @@ -9018,6 +9018,7 @@ export function Test2() { end: { line: 1, offset: 37 }, name: "fnA", matchKind: "prefix", + isCaseSensitive: true, kind: ScriptElementKind.functionElement, kindModifiers: "export,declare", }, @@ -9025,6 +9026,7 @@ export function Test2() { ...protocolFileSpanFromSubstring(bTs, "export function fnB() { fnA(); }"), name: "fnB", matchKind: "prefix", + isCaseSensitive: true, kind: ScriptElementKind.functionElement, kindModifiers: "export", } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 044f56da8ea..546a34d8bc0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6712,6 +6712,8 @@ declare namespace ts { function isNamedDeclaration(node: Node): node is NamedDeclaration & { name: DeclarationName; }; + /** @internal */ + function getNonAssignedNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. @@ -9864,7 +9866,7 @@ declare namespace ts { version: string; scriptSnapshot: IScriptSnapshot | undefined; nameTable: UnderscoreEscapedMap | undefined; - getNamedDeclarations(): Map; + getNamedDeclarations(): Map>; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineEndOfPosition(pos: number): number; getLineStarts(): ReadonlyArray; @@ -10243,7 +10245,7 @@ declare namespace ts { name: string; kind: ScriptElementKind; kindModifiers: string; - matchKind: string; + matchKind: "exact" | "prefix" | "substring" | "camelCase"; isCaseSensitive: boolean; fileName: string; textSpan: TextSpan; @@ -13118,8 +13120,8 @@ declare namespace ts.server.protocol { interface NavtoItem extends FileSpan { name: string; kind: ScriptElementKind; - matchKind?: string; - isCaseSensitive?: boolean; + matchKind: string; + isCaseSensitive: boolean; kindModifiers?: string; containerName?: string; containerKind?: ScriptElementKind; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8e67793a4c5..fb6d7b90cf4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4994,7 +4994,7 @@ declare namespace ts { name: string; kind: ScriptElementKind; kindModifiers: string; - matchKind: string; + matchKind: "exact" | "prefix" | "substring" | "camelCase"; isCaseSensitive: boolean; fileName: string; textSpan: TextSpan; diff --git a/tests/cases/fourslash/declarationExpressions.ts b/tests/cases/fourslash/declarationExpressions.ts index 7f2a64d8ecf..00891dc9459 100644 --- a/tests/cases/fourslash/declarationExpressions.ts +++ b/tests/cases/fourslash/declarationExpressions.ts @@ -1,30 +1,21 @@ /// -////class A {} -////const B = class C { +// @noLib: true + +////[|{| "name": "A", "kind": "class" |}class A {}|] +////const [|{| "name": "B", "kind": "const" |}B = [|{| "name": "Cz", "kind": "class" |}class Cz { //// public x; -////}; -////function D() {} -////const E = function F() {} +////}|]|]; +////[|{| "name": "D", "kind": "function" |}function D() {}|] +////const [|{| "name": "E", "kind": "const" |}E = [|{| "name": "F", "kind": "function" |}function F() {}|]|] ////console.log(function() {}, class {}); // Expression with no name should have no effect. -////console.log(function inner() {}); -////String(function fun() { class cls { public prop; } })); +////console.log([|{| "name": "inner", "kind": "function" |}function inner() {}|]); +////String([|{| "name": "nn", "kind": "function" |}function nn() { +//// [|{| "name": "cls", "kind": "class", "containerName": "nn", "containerKind": "function" |}class cls { +//// [|{| "name": "prop", "kind": "property", "kindModifiers": "public", "containerName": "cls", "containerKind": "class" |}public prop;|] +//// }|] +////}|])); -function navExact(name: string, kind: string) { - verify.navigationItemsListContains(name, kind, name, "exact"); +for (const range of test.ranges()) { + verify.navigateTo({ pattern: range.marker.data.name, expected: [{ ...range.marker.data, range }] }); } - -navExact("A", "class"); -navExact("B", "const"); -navExact("C", "class"); -navExact("x", "property"); - -navExact("D", "function"); -navExact("E", "const"); -navExact("F", "function") - -navExact("inner", "function"); - -navExact("fun", "function"); -navExact("cls", "class"); -navExact("prop", "property"); diff --git a/tests/cases/fourslash/declareFunction.ts b/tests/cases/fourslash/declareFunction.ts index 8806bc6d75e..8b9b18093b7 100644 --- a/tests/cases/fourslash/declareFunction.ts +++ b/tests/cases/fourslash/declareFunction.ts @@ -1,7 +1,5 @@ /// -//// /**/declare function +////declare function -goTo.marker(); -//verify there is no empty navigation item. -verify.navigationItemsListCount(0, "") +verify.navigateTo({ pattern: "", expected: [] }); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 0753ded25c9..bff9425edcd 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -289,8 +289,7 @@ declare namespace FourSlashInterface { navigationBar(json: any, options?: { checkSpans?: boolean }): void; navigationTree(json: any, options?: { checkSpans?: boolean }): void; - navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string): void; - navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void; + navigateTo(...options: VerifyNavigateToOptions[]); occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; occurrencesAtPositionCount(expectedCount: number): void; rangesAreDocumentHighlights(ranges?: Range[], options?: VerifyDocumentHighlightsOptions): void; @@ -568,6 +567,22 @@ declare namespace FourSlashInterface { tags?: ReadonlyArray; } + interface VerifyNavigateToOptions { + readonly pattern: string; + readonly fileName?: string; + readonly expected: ReadonlyArray; + } + interface ExpectedNavigateToItem { + readonly name: string; + readonly kind: string; + readonly kindModifiers?: string; // default: "" + readonly matchKind?: string; // default: "exact" + readonly isCaseSensitive?: boolean; // default: "true" + readonly range: Range; + readonly containerName?: string; // default: "" + readonly containerKind?: string; // default: ScriptElementKind.unknown + } + interface JSDocTagInfo { name: string; text: string | undefined; diff --git a/tests/cases/fourslash/incorrectJsDocObjectLiteralType.ts b/tests/cases/fourslash/incorrectJsDocObjectLiteralType.ts index ddf65ec0e8a..7932f42e827 100644 --- a/tests/cases/fourslash/incorrectJsDocObjectLiteralType.ts +++ b/tests/cases/fourslash/incorrectJsDocObjectLiteralType.ts @@ -1,8 +1,18 @@ /// -//// /**/ +// @Filename: /a.ts +//// -goTo.marker(); -verify.navigationItemsListCount(0, "foo", "exact"); +verify.navigateTo({ pattern: "", expected: [] }); edit.insert("/**\n * @typedef {Object} foo\n * @property {any} [obj]\n */\nexport default function foo() {\n}"); -verify.navigationItemsListContains("foo", "function", "foo", "exact"); +verify.navigateTo({ + pattern: "foo", + expected: [ + { + name: "foo", + kind: "function", + kindModifiers: "export", + range: { fileName: "/a.ts", pos: 58, end: 91 }, + }, + ], +}); diff --git a/tests/cases/fourslash/navigateItemsConst.ts b/tests/cases/fourslash/navigateItemsConst.ts index a20c0192874..b0bc97da111 100644 --- a/tests/cases/fourslash/navigateItemsConst.ts +++ b/tests/cases/fourslash/navigateItemsConst.ts @@ -1,16 +1,15 @@ /// -////{| "itemName": "c", "kind": "const", "parentName": "" |}const c = 10; +// @noLib: true + +////const [|{| "name": "c", "kind": "const" |}c = 10|]; ////function foo() { -//// {| "itemName": "d", "kind": "const", "parentName": "foo" |}const d = 10; +//// const [|{| "name": "d", "kind": "const", "containerName": "foo", "containerKind": "function" |}d = 10|]; ////} -test.markers().forEach(marker => { - verify.navigationItemsListContains( - marker.data.itemName, - marker.data.kind, - marker.data.itemName, - "exact", - marker.fileName, - marker.data.parentName); -}); \ No newline at end of file +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }) +} diff --git a/tests/cases/fourslash/navigateItemsExports.ts b/tests/cases/fourslash/navigateItemsExports.ts index 646d557aace..e1d92064f74 100644 --- a/tests/cases/fourslash/navigateItemsExports.ts +++ b/tests/cases/fourslash/navigateItemsExports.ts @@ -1,20 +1,19 @@ /// -////export { {| "itemName": "a", "kind": "alias", "parentName": "" |}a } from "a"; -//// -////export { {| "itemName": "B", "kind": "alias", "parentName": "" |}b as B } from "a"; -//// -////export { {| "itemName": "c", "kind": "alias", "parentName": "" |}c, -//// {| "itemName": "D", "kind": "alias", "parentName": "" |}d as D } from "a"; -//// -////{| "itemName": "f", "kind": "alias", "parentName": "" |}export import f = require("a"); +// @noLib: true -test.markers().forEach(marker => { - verify.navigationItemsListContains( - marker.data.itemName, - marker.data.kind, - marker.data.itemName, - "exact", - marker.fileName, - marker.data.parentName); -}); \ No newline at end of file +////export { [|{| "name": "a", "kind": "alias" |}a|] } from "a"; +//// +////export { [|{| "name": "B", "kind": "alias" |}b as B|] } from "a"; +//// +////export { [|{| "name": "c", "kind": "alias" |}c|], +//// [|{| "name": "D", "kind": "alias" |}d as D|] } from "a"; +//// +////[|{| "name": "f", "kind": "alias", "kindModifiers": "export" |}export import f = require("a");|] + +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +} diff --git a/tests/cases/fourslash/navigateItemsImports.ts b/tests/cases/fourslash/navigateItemsImports.ts index 8ac3e000639..0c8f1ace8a6 100644 --- a/tests/cases/fourslash/navigateItemsImports.ts +++ b/tests/cases/fourslash/navigateItemsImports.ts @@ -1,25 +1,26 @@ /// -////import {| "itemName": "ns", "kind": "alias", "parentName": "" |}* as ns from "a"; -//// -////import { {| "itemName": "a", "kind": "alias", "parentName": "" |}a } from "a"; -//// -////import { {| "itemName": "B", "kind": "alias", "parentName": "" |}b as B } from "a"; -//// -////import { {| "itemName": "c", "kind": "alias", "parentName": "" |}c, -//// {| "itemName": "D", "kind": "alias", "parentName": "" |}d as D } from "a"; -//// -////import {| "itemName": "d1", "kind": "alias", "parentName": "" |}d1, { -//// {| "itemName": "e", "kind": "alias", "parentName": "" |}e } from "a"; -//// -////{| "itemName": "f", "kind": "alias", "parentName": "" |}import f = require("a"); +// @noLib: true -test.markers().forEach(marker => { - verify.navigationItemsListContains( - marker.data.itemName, - marker.data.kind, - marker.data.itemName, - "exact", - marker.fileName, - marker.data.parentName); -}); \ No newline at end of file +////import [|{| "name": "ns", "kind": "alias" |}* as ns|] from "a"; +//// +////import { [|{| "name": "a", "kind": "alias" |}a|] } from "a"; +//// +////import { [|{| "name": "B", "kind": "alias" |}b as B|] } from "a"; +//// +////import { [|{| "name": "c", "kind": "alias" |}c|], +//// [|{| "name": "dee", "kind": "alias" |}d as dee|] } from "a"; +//// +////import [|{| "name": "d1", "kind": "alias" |}d1|], { +//// [|{| "name": "e", "kind": "alias" |}e|] } from "a"; +//// +////[|{| "name": "f", "kind": "alias" |}import f = require("a");|] + +// TODO: GH#25237 (range for `d1` is too big) + +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +} diff --git a/tests/cases/fourslash/navigateItemsLet.ts b/tests/cases/fourslash/navigateItemsLet.ts index 8d6886ceb69..96d134573e3 100644 --- a/tests/cases/fourslash/navigateItemsLet.ts +++ b/tests/cases/fourslash/navigateItemsLet.ts @@ -1,16 +1,14 @@ /// -////{| "itemName": "c", "kind": "let", "parentName": "" |}let c = 10; +// @noLib: true + +////let [|c = 10|]; ////function foo() { -//// {| "itemName": "d", "kind": "let", "parentName": "foo" |}let d = 10; +//// let [|d = 10|]; ////} -test.markers().forEach(marker => { - verify.navigationItemsListContains( - marker.data.itemName, - marker.data.kind, - marker.data.itemName, - "exact", - marker.fileName, - marker.data.parentName); -}); \ No newline at end of file +const [r0, r1] = test.ranges(); +verify.navigateTo( + { pattern: "c", expected: [{ name: "c", kind: "let", range: r0 }] }, + { pattern: "d", expected: [{ name: "d", kind: "let", range: r1, containerName: "foo", containerKind: "function" }] }, +); diff --git a/tests/cases/fourslash/navigateToIIFE.ts b/tests/cases/fourslash/navigateToIIFE.ts index 69632e5f1ec..acf16850649 100644 --- a/tests/cases/fourslash/navigateToIIFE.ts +++ b/tests/cases/fourslash/navigateToIIFE.ts @@ -1,19 +1,26 @@ /// -// @Filename: file1.ts -/////*1*/(function () { +// @Filename: /a.ts +////(function () { //// "use strict"; -//// function onResume() { -//// }; +//// [|function onResume() { +//// }|]; ////} )(); -// @Filename: file2.ts -/////*2*/class EventManager { -//// public onResume(name: string) { } +// @Filename: /b.ts +////class EventManager { +//// [|{| "containerName": "EventManager" |}public onResume(name: string) { }|] ////} ////class MyOtherEventManager { -//// public onResume(name: string) { } +//// [|{| "containerName": "MyOtherEventManager" |}public onResume(name: string) { }|] ////} -verify.navigationItemsListCount(3, "onResume"); -verify.navigationItemsListCount(1, "onResume", undefined, test.marker("1").fileName); -verify.navigationItemsListContains("onResume", "function", "onResume", "exact", test.marker("1").fileName); -verify.navigationItemsListCount(2, "onResume", undefined, test.marker("2").fileName); + +const [r0, r1, r2] = test.ranges(); +const aTs: ReadonlyArray = [{ name: "onResume", kind: "function", range: r0 }]; +const bTs: ReadonlyArray = [r1, r2].map((range): FourSlashInterface.ExpectedNavigateToItem => + ({ name: "onResume", kind: "method", kindModifiers: "public", range, containerName: range.marker.data.containerName, containerKind: "class" })); + +verify.navigateTo( + { pattern: "onResume", expected: [...aTs, ...bTs] }, + { pattern: "onResume", fileName: "/a.ts", expected: aTs }, + { pattern: "onResume", fileName: "/b.ts", expected: bTs }, +); diff --git a/tests/cases/fourslash/navigateToImport.ts b/tests/cases/fourslash/navigateToImport.ts index 7247d443c4f..afb85fa7eed 100644 --- a/tests/cases/fourslash/navigateToImport.ts +++ b/tests/cases/fourslash/navigateToImport.ts @@ -1,14 +1,14 @@ /// // @Filename: library.ts -////export function foo() {} -////export function bar() {} +////[|export function foo() {}|] +////[|export function bar() {}|] // @Filename: user.ts -////import {foo, bar as baz} from './library'; +////import {foo, [|bar as baz|]} from './library'; -verify.navigationItemsListCount(1, "foo"); -verify.navigationItemsListContains("foo", "function", "foo", "exact"); -verify.navigationItemsListCount(1, "bar"); -verify.navigationItemsListContains("bar", "function", "bar", "exact"); -verify.navigationItemsListCount(1, "baz"); -verify.navigationItemsListContains("baz", "alias", "baz", "exact"); +const [r0, r1, r2] = test.ranges(); +verify.navigateTo( + { pattern: "foo", expected: [{ name: "foo", kind: "function", kindModifiers: "export", range: r0 }] }, + { pattern: "bar", expected: [{ name: "bar", kind: "function", kindModifiers: "export", range: r1 }] }, + { pattern: "baz", expected: [{ name: "baz", kind: "alias", range: r2 }] }, +); diff --git a/tests/cases/fourslash/navigateToQuoted.ts b/tests/cases/fourslash/navigateToQuoted.ts index 6cc3533c084..4324ec75abe 100644 --- a/tests/cases/fourslash/navigateToQuoted.ts +++ b/tests/cases/fourslash/navigateToQuoted.ts @@ -3,10 +3,24 @@ // @noLib: true ////class C { -//// ["foo-bar"]() {} -//// ["foo bar"]() {} +//// [|["foo-bar"]() {}|] +//// [|["foo bar"]() {}|] ////} -verify.navigationItemsListContains("foo-bar", "method", "foo-bar", "exact", undefined, "C"); -// TODO: GH#23035 -// verify.navigationItemsListContains("foo bar", "method", "foo bar", "exact", undefined, "C"); +const [r0, r1] = test.ranges(); +const dash: FourSlashInterface.ExpectedNavigateToItem = + { name: "foo-bar", kind: "method", range: r0, containerName: "C", containerKind: "class" }; +const space: FourSlashInterface.ExpectedNavigateToItem = + { name: "foo bar", kind: "method", range: r1, containerName: "C", containerKind: "class" }; + +verify.navigateTo( + { + pattern: "foo-bar", + expected: [dash, { ...space, matchKind: "prefix" }], + }, + { + pattern: "foo bar", + // TODO: GH#23035 + expected: [{ ...space, matchKind: "prefix" }, { ...dash, matchKind: "prefix" }], + }, +); diff --git a/tests/cases/fourslash/navigateToSingleFileResults.ts b/tests/cases/fourslash/navigateToSingleFileResults.ts index db9d169840c..988c47884c3 100644 --- a/tests/cases/fourslash/navigateToSingleFileResults.ts +++ b/tests/cases/fourslash/navigateToSingleFileResults.ts @@ -1,19 +1,27 @@ /// -// @Filename: file1.ts -/////*1*/class Greeter { -//// public hello(name: string) { } +// @Filename: /a.ts +////class Greeter { +//// [|public hello(name: string) { }|] ////} ////var x = new Greeter(); -// @Filename: file2.ts -/////*2*/class MyGreeter { -//// public hello(name: string) { } +// @Filename: /b.ts +////class MyGreeter { +//// [|{| "containerName": "MyGreeter" |}public hello(name: string) { }|] ////} ////class MyOtherGreeter { -//// public hello(name: string) { } +//// [|{| "containerName": "MyOtherGreeter" |}public hello(name: string) { }|] ////} -verify.navigationItemsListCount(3, "hello"); -verify.navigationItemsListCount(1, "hello", undefined, test.marker("1").fileName); -verify.navigationItemsListContains("hello", "method", "hello", "exact", test.marker("1").fileName); -verify.navigationItemsListCount(2, "hello", undefined, test.marker("2").fileName); +const [r0, r1, r2] = test.ranges(); +const aTs: ReadonlyArray = [ + { name: "hello", kind: "method", kindModifiers: "public", range: r0, containerName: "Greeter", containerKind: "class" }, +]; +const bTs: ReadonlyArray = [r1, r2].map((range): FourSlashInterface.ExpectedNavigateToItem => + ({ name: "hello", kind: "method", kindModifiers: "public", range, containerName: range.marker.data.containerName, containerKind: "class" })); + +verify.navigateTo( + { pattern: "hello", expected: [...aTs, ...bTs] }, + { pattern: "hello", fileName: "/a.ts", expected: aTs }, + { pattern: "hello", fileName: "/b.ts", expected: bTs }, +); diff --git a/tests/cases/fourslash/navigateToSymbolIterator.ts b/tests/cases/fourslash/navigateToSymbolIterator.ts index 28c408f99fe..e26e81f7496 100644 --- a/tests/cases/fourslash/navigateToSymbolIterator.ts +++ b/tests/cases/fourslash/navigateToSymbolIterator.ts @@ -1,7 +1,12 @@ /// ////class C { -//// [Symbol.iterator]() {} +//// [|[Symbol.iterator]() {}|] ////} -verify.navigationItemsListContains("iterator", "method", "iterator", "exact", undefined, "C"); +verify.navigateTo({ + pattern: "iterator", + expected: [ + { name: "iterator", kind: "method", range: test.ranges()[0], containerName: "C", containerKind: "class" }, + ], +}); diff --git a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts index 4c441728fdf..73bf8c1f2fe 100644 --- a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts +++ b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts @@ -1,3 +1,5 @@ +/// + ////import *{} from 'foo'; verify.navigationTree({ diff --git a/tests/cases/fourslash/navigationItemsComputedProperties.ts b/tests/cases/fourslash/navigationItemsComputedProperties.ts index 3c2ead0d2b4..9febc63954d 100644 --- a/tests/cases/fourslash/navigationItemsComputedProperties.ts +++ b/tests/cases/fourslash/navigationItemsComputedProperties.ts @@ -1,20 +1,16 @@ /// -////{| "itemName": "C", "kind": "class", "parentName": "" |} -////class C { -//// {| "itemName": "foo", "kind": "method", "parentName": "C" |} -//// foo() { } -//// ["hi" + "bye"]() { } -//// {| "itemName": "bar", "kind": "method", "parentName": "C" |} -//// bar() { } -////} +// @noLib: true -test.markers().forEach(marker => { - verify.navigationItemsListContains( - marker.data.itemName, - marker.data.kind, - marker.data.itemName, - "exact", - marker.fileName, - marker.data.parentName); -}); \ No newline at end of file +////[|{| "name": "C", "kind": "class" |}class C { +//// [|{| "name": "foo", "kind": "method", "containerName": "C", "containerKind": "class" |}foo() { }|] +//// ["hi" + "bye"]() { } +//// [|{| "name": "bar", "kind": "method", "containerName": "C", "containerKind": "class" |}bar() { }|] +////}|] + +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +} diff --git a/tests/cases/fourslash/navigationItemsExactMatch.ts b/tests/cases/fourslash/navigationItemsExactMatch.ts index 5481f4295cb..330706f682f 100644 --- a/tests/cases/fourslash/navigationItemsExactMatch.ts +++ b/tests/cases/fourslash/navigationItemsExactMatch.ts @@ -1,27 +1,22 @@ /// -/////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { -//// -//// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point { -//// // Instance member -//// {| "itemName": "origin", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private origin = 0.0; -//// -//// {| "itemName": "distFromZero", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private distFromZero = 0.0; -//// -//// // Getter -//// {| "itemName": "distance", "kind": "getter", "parentName": "Point", "matchKind": "exact" |}get distance(): number { return 0; } -//// } -////} -//// -////// Local variables -////{| "itemName": "point", "kind": "var", "parentName": "", "matchKind": "exact"|}var point = new Shapes.Point(); +// @noLib: true -//// Testing for exact matching of navigationItems +////[|{| "name": "Shapes", "kind": "module" |}module Shapes { +//// [|{| "name": "Point", "kind": "class", "kindModifiers": "export", "containerName": "Shapes", "containerKind": "module" |}export class Point { +//// [|{| "name": "origin", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private origin = 0.0;|] +//// +//// [|{| "name": "distFromZero", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private distFromZero = 0.0;|] +//// +//// [|{| "name": "distance", "kind": "getter", "containerName": "Point", "containerKind": "class" |}get distance(): number { return 0; }|] +//// }|] +////}|] +//// +////var [|{| "name": "xyz", "kind": "var" |}xyz = new Shapes.Point()|]; -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationItemsListContains(marker.data.itemName, marker.data.kind, marker.data.itemName, marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +} diff --git a/tests/cases/fourslash/navigationItemsExactMatch2.ts b/tests/cases/fourslash/navigationItemsExactMatch2.ts index 1bf4552a49b..84686bbf969 100644 --- a/tests/cases/fourslash/navigationItemsExactMatch2.ts +++ b/tests/cases/fourslash/navigationItemsExactMatch2.ts @@ -1,28 +1,50 @@ /// -// @Filename: navigationItemsContainsNoAnonymousFunctions_0.ts -/////*file1*/ + ////module Shapes { -//// class Point { -//// private _origin = 0.0; -//// private distanceFromA = 0.0; +//// [|class Point { +//// [|private _origin = 0.0;|] +//// [|private distanceFromA = 0.0;|] //// -//// get distance1(distanceParam): number { -//// var distanceLocal; +//// [|get distance1(distanceParam): number { +//// var [|distanceLocal|]; //// return 0; -//// } -//// } +//// }|] +//// }|] ////} //// -////var point = new Shapes.Point(); -////function distance2(distanceParam1): void { -//// var distanceLocal1; -////} +////var [|point = new Shapes.Point()|]; +////[|function distance2(distanceParam1): void { +//// var [|distanceLocal1|]; +////}|] -goTo.marker("file1"); -verify.navigationItemsListCount(2, "point", "exact"); -verify.navigationItemsListCount(5, "distance", "prefix"); -verify.navigationItemsListCount(1, "origin", "substring"); +const [r_Point, r_origin, r_distanceFromA, r_distance1, r_distanceLocal, r_point, r_distance2, r_distanceLocal1] = test.ranges(); -verify.navigationItemsListCount(0, "square", "exact"); -verify.navigationItemsListCount(0, "square", "prefix"); -verify.navigationItemsListCount(0, "square", "substring"); \ No newline at end of file +verify.navigateTo( + { + pattern: "point", + expected: [ + { name: "point", kind: "var", range: r_point }, + { name: "Point", kind: "class", isCaseSensitive: false, range: r_Point, containerName: "Shapes", containerKind: "module" }, + ], + }, + { + pattern: "distance", + expected: [ + { name: "distance1", matchKind: "prefix", kind: "getter", range: r_distance1, containerName: "Point", containerKind: "class" }, + { name: "distance2", matchKind: "prefix", kind: "function", range: r_distance2 }, + { name: "distanceFromA", matchKind: "prefix", kind: "property", kindModifiers: "private", range: r_distanceFromA, containerName: "Point", containerKind: "class" }, + { name: "distanceLocal", matchKind: "prefix", kind: "var", range: r_distanceLocal, containerName: "distance1", containerKind: "getter" }, + { name: "distanceLocal1", matchKind: "prefix", kind: "var", range: r_distanceLocal1, containerName: "distance2", containerKind: "function" }, + ], + }, + { + pattern: "origin", + expected: [ + { name: "_origin", matchKind: "substring", kind: "property", kindModifiers: "private", range: r_origin, containerName: "Point", containerKind: "class" }, + ], + }, + { + pattern: "square", + expected: [], + } +); diff --git a/tests/cases/fourslash/navigationItemsInConstructorsExactMatch.ts b/tests/cases/fourslash/navigationItemsInConstructorsExactMatch.ts index 5c6cf91a40a..1db5e13786c 100644 --- a/tests/cases/fourslash/navigationItemsInConstructorsExactMatch.ts +++ b/tests/cases/fourslash/navigationItemsInConstructorsExactMatch.ts @@ -1,13 +1,20 @@ /// +// @noLib: true + ////class Test { -//// private search1: number; -//// constructor(public search2: boolean, readonly search3: string, search4: string) { +//// [|private search1: number;|] +//// constructor([|public search2: boolean|], [|readonly search3: string|], search4: string) { //// } ////} // Search for properties defined in the constructor, but not other constructor paramters -var searchValue = "search"; -verify.navigationItemsListContains("search1", "property", searchValue, "prefix"); -verify.navigationItemsListContains("search2", "property", searchValue, "prefix"); -verify.navigationItemsListContains("search3", "property", searchValue, "prefix"); +const [r0, r1, r2] = test.ranges(); +verify.navigateTo({ + pattern: "search", + expected: [ + { name: "search1", matchKind: "prefix", kind: "property", kindModifiers: "private", range: r0, containerName: "Test", containerKind: "class" }, + { name: "search2", matchKind: "prefix", kind: "property", kindModifiers: "public", range: r1, containerName: "Test", containerKind: "class" }, + { name: "search3", matchKind: "prefix", kind: "property", range: r2, containerName: "Test", containerKind: "class" }, + ], +}); diff --git a/tests/cases/fourslash/navigationItemsOverloads1.ts b/tests/cases/fourslash/navigationItemsOverloads1.ts index 68d0c8d1f83..55b35f00c75 100644 --- a/tests/cases/fourslash/navigationItemsOverloads1.ts +++ b/tests/cases/fourslash/navigationItemsOverloads1.ts @@ -4,12 +4,12 @@ ////function overload(b: boolean): boolean; ////function overload(b: number): boolean; ////function overload(f: typeof overload): boolean; -////function overload(x: any, b = (function overload() { return false })): boolean { +////[|function overload(x: any, b = (function overload() { return false })): boolean { //// throw overload; -////} +////}|] //// ////interface I { -//// interfaceMethodSignature(a: string): boolean; +//// [|interfaceMethodSignature(a: string): boolean;|] //// interfaceMethodSignature(b: boolean): boolean; //// interfaceMethodSignature(b: number): boolean; //// interfaceMethodSignature(f: I): boolean; @@ -20,11 +20,30 @@ //// methodOverload(b: boolean): boolean; //// methodOverload(b: number): boolean; //// methodOverload(f: I): boolean; -//// methodOverload(x: any, b = (function overload() { return false })): boolean { +//// [|methodOverload(x: any, b = (function overload() { return false })): boolean { //// throw C; -//// } +//// }|] ////} -verify.navigationItemsListCount(1, "overload", "exact"); -verify.navigationItemsListCount(1, "interfaceMethodSignature", "exact"); -verify.navigationItemsListCount(1, "methodOverload", "exact"); +const [r0, r1, r2] = test.ranges(); +const methodOverload: FourSlashInterface.ExpectedNavigateToItem = + { name: "methodOverload", kind: "method", range: r2, containerName: "C", containerKind: "class" }; +verify.navigateTo( + { + pattern: "overload", + expected: [ + { name: "overload", kind: "function", range: r0 }, + { ...methodOverload, matchKind: "substring", isCaseSensitive: false }, + ] + }, + { + pattern: "interfaceMethodSignature", + expected: [ + { name: "interfaceMethodSignature", kind: "method", range: r1, containerName: "I", containerKind: "interface" }, + ], + }, + { + pattern: "methodOverload", + expected: [methodOverload], + }, +); diff --git a/tests/cases/fourslash/navigationItemsOverloads2.ts b/tests/cases/fourslash/navigationItemsOverloads2.ts index 2c33ef65f0d..3a6e850c770 100644 --- a/tests/cases/fourslash/navigationItemsOverloads2.ts +++ b/tests/cases/fourslash/navigationItemsOverloads2.ts @@ -1,12 +1,16 @@ /// ////interface I { -//// interfaceMethodSignature(a: string): boolean; +//// [|interfaceMethodSignature(a: string): boolean;|] //// interfaceMethodSignature(b: number): boolean; //// interfaceMethodSignature(f: I): boolean; ////} ////interface I { -//// interfaceMethodSignature(b: boolean): boolean; +//// [|interfaceMethodSignature(b: boolean): boolean;|] ////} -verify.navigationItemsListCount(2, "interfaceMethodSignature", "exact"); +verify.navigateTo({ + pattern: "interfaceMethodSignature", + expected: test.ranges().map(range => + ({ name: "interfaceMethodSignature", kind: "method", range, containerName: "I", containerKind: "interface" })), +}); diff --git a/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts b/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts index 21b7d33dd41..b30a24ba3f4 100644 --- a/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts +++ b/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts @@ -7,9 +7,9 @@ ////var x= '?'; //// ////function overload1(f: typeof overload): boolean; -////function overload1(x: any, b = (function overload() { return false })): boolean { +////[|function overload1(x: any, b = (function overload() { return false })): boolean { //// throw overload; -////} +////}|] ////function overload2(a: string): boolean; ////function overload2(b: boolean): boolean; @@ -20,10 +20,26 @@ ////} //// ////function overload2(f: typeof overload): boolean; -////function overload2(x: any, b = (function overload() { return false })): boolean { +////[|function overload2(x: any, b = (function overload() { return false })): boolean { //// throw overload; -////} +////}|] -verify.navigationItemsListCount(1, "overload1", "exact"); -verify.navigationItemsListCount(1, "overload2", "exact"); -verify.navigationItemsListCount(2, "overload", "prefix"); \ No newline at end of file +const [r0, r1] = test.ranges(); +const overload1: FourSlashInterface.ExpectedNavigateToItem = + { name: "overload1", kind: "function", range: r0 }; +const overload2: FourSlashInterface.ExpectedNavigateToItem = + { name: "overload2", kind: "function", range: r1 }; +verify.navigateTo( + { + pattern: "overload1", + expected: [overload1], + }, + { + pattern: "overload2", + expected: [overload2], + }, + { + pattern: "overload", + expected: [{ ...overload1, matchKind: "prefix" }, { ...overload2, matchKind: "prefix" }], + } +); diff --git a/tests/cases/fourslash/navigationItemsOverloadsBroken2.ts b/tests/cases/fourslash/navigationItemsOverloadsBroken2.ts index 6b039322419..eb1e9dcc11c 100644 --- a/tests/cases/fourslash/navigationItemsOverloadsBroken2.ts +++ b/tests/cases/fourslash/navigationItemsOverloadsBroken2.ts @@ -2,22 +2,39 @@ ////function overload1(a: string): boolean; ////function overload1(b: boolean): boolean; -////function overload1(x: any, b = (function overload() { return false })): boolean { +////[|function overload1(x: any, b = (function overload() { return false })): boolean { //// throw overload1; -////} +////}|] ////function overload1(b: number): boolean; ////function overload1(f: typeof overload): boolean; ////function overload2(a: string): boolean; ////function overload2(b: boolean): boolean; -////function overload2(x: any, b = (function overload() { return false })): boolean { -//// function overload2(): boolean; +////[|function overload2(x: any, b = (function overload() { return false })): boolean { +//// [|function overload2(): boolean;|] //// function overload2(x: any): boolean; //// throw overload2; -////} -////function overload2(b: number): boolean; +////}|] +////[|function overload2(b: number): boolean;|] ////function overload2(f: typeof overload): boolean; -verify.navigationItemsListCount(1, "overload1", "exact"); -verify.navigationItemsListCount(3, "overload2", "exact"); -verify.navigationItemsListCount(4, "overload", "prefix"); \ No newline at end of file +const [r0, r1, r2, r3] = test.ranges(); +const overload1: ReadonlyArray = [ + { name: "overload1", kind: "function", range: r0 }, +]; +const overload2: ReadonlyArray = [ + { name: "overload2", kind: "function", range: r1 }, + { name: "overload2", kind: "function", range: r2, containerName: "overload2", containerKind: "function" }, + { name: "overload2", kind: "function", range: r3 }, +]; +verify.navigateTo( + { pattern: "overload1", expected: overload1 }, + { + pattern: "overload2", + expected: overload2, + }, + { + pattern: "overload", + expected: [...overload1, ...overload2].map(item => ({ ...item, matchKind: "prefix" })), + }, +); diff --git a/tests/cases/fourslash/navigationItemsPrefixMatch.ts b/tests/cases/fourslash/navigationItemsPrefixMatch.ts index b295def114f..be43f909c86 100644 --- a/tests/cases/fourslash/navigationItemsPrefixMatch.ts +++ b/tests/cases/fourslash/navigationItemsPrefixMatch.ts @@ -1,29 +1,23 @@ /// -/////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { -//// -//// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point { -//// // Instance member -//// {| "itemName": "originality", "kind": "property", "parentName": "Point", "matchKind": "prefix"|}private originality = 0.0; -//// -//// {| "itemName": "distanceFromOrig", "kind": "property", "parentName": "Point", "matchKind": "prefix"|}private distanceFromOrig = 0.0; -//// -//// // Getter -//// {| "itemName": "distanceFarFarAway", "kind": "getter", "parentName": "Point", "matchKind": "prefix" |}get distanceFarFarAway(): number { return 0; } -//// } -////} -//// -////// Local variables -////{| "itemName": "pointsSquareBox", "kind": "var", "parentName": "", "matchKind": "prefix" |}var pointsSquareBox = new Shapes.Point(); +// @noLib: true -//// Testing for exact matching of navigationItems -// var searchValue = "origin distance points shape"; +////[|{| "name": "Shapes", "kind": "module" |}module Shapes { +//// [|{| "name": "Point", "kind": "class", "kindModifiers": "export", "containerName": "Shapes", "containerKind": "module" |}export class Point { +//// [|{| "name": "originality", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private originality = 0.0;|] +//// +//// [|{| "name": "distanceFromOrig", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private distanceFromOrig = 0.0;|] +//// +//// [|{| "name": "distanceFarFarAway", "kind": "getter", "containerName": "Point", "containerKind": "class" |}get distanceFarFarAway(): number { return 0; }|] +//// }|] +////}|] +//// +////var [|{| "name": "xyz", "kind": "var" |}xyz = new Shapes.Point()|]; -test.markers().forEach((marker) => { - if (marker.data) { - var itemName = marker.data.itemName; - verify.navigationItemsListContains(itemName, marker.data.kind, itemName.substr(0, itemName.length - 1), marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); +for (const range of test.ranges()) { + const { name } = range.marker.data; + verify.navigateTo({ + pattern: name.slice(0, name.length - 1), + expected: [{ ...range.marker.data, range, matchKind: "prefix" }], + }); +} diff --git a/tests/cases/fourslash/navigationItemsPrefixMatch2.ts b/tests/cases/fourslash/navigationItemsPrefixMatch2.ts index 0bce1f36b33..fa0a9d38101 100644 --- a/tests/cases/fourslash/navigationItemsPrefixMatch2.ts +++ b/tests/cases/fourslash/navigationItemsPrefixMatch2.ts @@ -1,32 +1,46 @@ /// -// @Filename: navigationItemsContainsNoAnonymousFunctions_0.ts -/////*file1*/ + ////module Shapes { //// export class Point { -//// private originality = 0.0; -//// private distanceFromOrig = 0.0; -//// get distanceFarFarAway(distanceFarFarAwayParam: number): number { -//// var distanceFarFarAwayLocal; +//// [|private originality = 0.0;|] +//// [|private distanceFromOrig = 0.0;|] +//// [|get distanceFarFarAway(distanceFarFarAwayParam: number): number { +//// var [|distanceFarFarAwayLocal|]; //// return 0; -//// } +//// }|] //// } ////} ////var pointsSquareBox = new Shapes.Point(); ////function PointsFunc(): void { //// var pointFuncLocal; ////} -////interface OriginI { -//// var 123; -//// var origin1; -//// public _distance(distanceParam): void; -////} +////[|interface OriginI { +//// 123; +//// [|origin1;|] +//// [|public _distance(distanceParam): void;|] +////}|] -var notFoundSearchValue = "mPointThatIJustInitiated wrongKeyWord"; - -goTo.marker("file1"); -verify.navigationItemsListCount(3, "origin", "prefix"); -verify.navigationItemsListCount(3, "distance", "prefix"); - -verify.navigationItemsListCount(0, notFoundSearchValue, "exact"); -verify.navigationItemsListCount(0, notFoundSearchValue, "prefix"); -verify.navigationItemsListCount(0, notFoundSearchValue, "substring"); \ No newline at end of file +const [r0, r1, r2, r3, r4, r5, r6] = test.ranges(); +verify.navigateTo( + { + pattern: "origin", + expected: [ + { name: "origin1", matchKind: "prefix", kind: "property", range: r5, containerName: "OriginI", containerKind: "interface" }, + { name: "originality", matchKind: "prefix", kind: "property", kindModifiers: "private", range: r0, containerName: "Point", containerKind: "class" }, + { name: "OriginI", matchKind: "prefix", isCaseSensitive: false, kind: "interface", range: r4 }, + ], + }, + { + pattern: "distance", + expected: [ + { name: "distanceFarFarAway", matchKind: "prefix", kind: "getter", range: r2, containerName: "Point", containerKind: "class" }, + { name: "distanceFarFarAwayLocal", matchKind: "prefix", kind: "var", range: r3, containerName: "distanceFarFarAway", containerKind: "getter" }, + { name: "distanceFromOrig", matchKind: "prefix", kind: "property", kindModifiers: "private", range: r1, containerName: "Point", containerKind: "class" }, + { name: "_distance", matchKind: "substring", kind: "method", kindModifiers: "public", range: r6, containerName: "OriginI", containerKind: "interface" }, + ], + }, + { + pattern: "mPointThatIJustInitiated wrongKeyWord", + expected: [], + }, +); diff --git a/tests/cases/fourslash/navigationItemsSpecialPropertyAssignment.ts b/tests/cases/fourslash/navigationItemsSpecialPropertyAssignment.ts index 4618d34b954..5d0eb58cc9d 100644 --- a/tests/cases/fourslash/navigationItemsSpecialPropertyAssignment.ts +++ b/tests/cases/fourslash/navigationItemsSpecialPropertyAssignment.ts @@ -1,20 +1,41 @@ /// +// @noLib: true // @allowJs: true -// @Filename: /a.js -////exports.{| "name": "x", "kind": "const" |}x = 0; -////exports.{| "name": "y", "kind": "function" |}y = function() {}; -////function Cls() { -//// this.{| "name": "prop", "kind": "property" |}prop = 0; -////} -////Cls.{| "name": "staticMethod", "kind": "method" |}staticMethod = function() {}; -////Cls.{| "name": "staticProperty", "kind": "property" |}staticProperty = 0; -////Cls.prototype.{| "name": "instance", "kind": "method" |}instance = function() {}; -for (const marker of test.markers()) { - verify.navigationItemsListContains( - marker.data.name, - marker.data.kind, - marker.data.name, - "exact"); -} +// @Filename: /a.js +////[|exports.x = 0|]; +////[|exports.y = function() {}|]; +////function Cls() { +//// [|this.instanceProp = 0|]; +////} +////[|Cls.staticMethod = function() {}|]; +////[|Cls.staticProperty = 0|]; +////[|Cls.prototype.instanceMethod = function() {}|]; + +const [rX, rY0, rInstanceProp, rStaticMethod, rStaticProp, rInstanceMethod] = test.ranges(); +verify.navigateTo( + { pattern: "x", expected: [{ name: "x", kind: "const", range: rX }] }, + { + pattern: "y", + expected: [{ name: "y", kind: "function", range: rY0 }], + }, + { + pattern: "instanceProp", + expected: [ + { name: "instanceProp", kind: "property", range: rInstanceProp, containerName: "Cls", containerKind: "function" }, + ], + }, + { + pattern: "staticMethod", + expected: [{ name: "staticMethod", kind: "method", range: rStaticMethod }], + }, + { + pattern: "staticProperty", + expected: [{ name: "staticProperty", kind: "property", range: rStaticProp }], + }, + { + pattern: "instanceMethod", + expected: [{ name: "instanceMethod", kind: "method", range: rInstanceMethod }], + }, +); diff --git a/tests/cases/fourslash/navigationItemsSubStringMatch.ts b/tests/cases/fourslash/navigationItemsSubStringMatch.ts index 071a1ae212f..3971cd4cba2 100644 --- a/tests/cases/fourslash/navigationItemsSubStringMatch.ts +++ b/tests/cases/fourslash/navigationItemsSubStringMatch.ts @@ -1,25 +1,24 @@ /// /////// Module -////{| "itemName": "MyShapes", "kind": "module", "parentName": "", "matchKind": "substring" |}module MyShapes { +////[|{| "name": "MyShapes", "kind": "module" |}module MyShapes { //// //// // Class -//// {| "itemName": "MyPoint", "kind": "class", "parentName": "MyShapes", "matchKind": "substring" |}export class MyPoint { +//// [|{| "name": "MyPoint", "kind": "class", "kindModifiers": "export", "containerName": "MyShapes", "containerKind": "module" |}export class MyPoint { //// // Instance member -//// {| "itemName": "MyoriginPointAttheHorizon", "kind": "property", "parentName": "MyPoint", "matchKind": "substring"|}private MyoriginPointAttheHorizon = 0.0; +//// [|{| "name": "MyoriginAttheHorizon", "kind": "property", "kindModifiers": "private", "containerName": "MyPoint", "containerKind": "class" |}private MyoriginAttheHorizon = 0.0;|] //// //// // Getter -//// {| "itemName": "MydistanceFromOrigin", "kind": "getter", "parentName": "MyPoint", "matchKind": "substring" |}get MydistanceFromOrigin(): number { return 0; } -//// -//// } -////} +//// [|{| "name": "MydistanceFromOrigin", "kind": "getter", "containerName": "MyPoint", "containerKind": "class" |}get MydistanceFromOrigin(): number { return 0; }|] +//// }|] +////}|] //// ////// Local variables -////{| "itemName": "MymyPointThatIJustInitiated", "kind": "var", "parentName": "", "matchKind": "substring"|}var MymyPointThatIJustInitiated = new Shapes.Point(); +////var [|{| "name": "MyXyz", "kind": "var" |}MyXyz = new Shapes.Point()|]; -test.markers().forEach((marker) => { - if (marker.data) { - var name = marker.data.itemName; - verify.navigationItemsListContains(name, marker.data.kind, name.substr(2), marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); \ No newline at end of file +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name.slice(2), + expected: [{ ...range.marker.data, range, matchKind: "substring" }], + }) +} diff --git a/tests/cases/fourslash/navigationItemsSubStringMatch2.ts b/tests/cases/fourslash/navigationItemsSubStringMatch2.ts index 5c7e3e5d202..a95b4a97511 100644 --- a/tests/cases/fourslash/navigationItemsSubStringMatch2.ts +++ b/tests/cases/fourslash/navigationItemsSubStringMatch2.ts @@ -1,35 +1,61 @@ /// -// @Filename: navigationItemsContainsNoAnonymousFunctions_0.ts -/////*file1*/ + ////module Shapes { //// export class Point { -//// private originPointAttheHorizon = 0.0; +//// [|private originPointAtTheHorizon = 0.0;|] //// -//// get distanceFromOrigin(distanceParam): number { -//// var distanceLocal; +//// [|get distanceFromOrigin(distanceParam): number { +//// var [|distanceLocal|]; //// return 0; -//// } +//// }|] //// } ////} //// -////var myPointThatIJustInitiated = new Shapes.Point(); -////interface IDistance{ -//// INITIATED123; -//// public horizon(): void; -////} -var notFoundSearchValue = "mPointThatIJustInitiated wrongKeyWord"; +////var [|myPointThatIJustInitiated = new Shapes.Point()|]; +////[|interface IDistance{ +//// [|INITIATED123;|] +//// [|public horizon(): void;|] +////}|] -goTo.marker("file1"); -// case sensitive matching for 'Horizon' will fail -verify.navigationItemsListCount(1, "Horizon", "exact"); -// case insensitive matching will find 'horizon' -verify.navigationItemsListCount(1, "horizon", "exact"); -// case sensitive matching will find 'Distance' and INITIATED -verify.navigationItemsListCount(1, "Distance", "substring"); -// case sensitive matching will find 'INITIATED' -verify.navigationItemsListCount(1, "INITIATED", "prefix"); +const [r0, r1, r2, r3, r4, r5, r6] = test.ranges() +const horizon: FourSlashInterface.ExpectedNavigateToItem = + { name: "horizon", kind: "method", kindModifiers: "public", range: r6, containerName: "IDistance", containerKind: "interface" }; +const origin: FourSlashInterface.ExpectedNavigateToItem = + { name: "originPointAtTheHorizon", kind: "property", kindModifiers: "private", range: r0, containerName: "Point", containerKind: "class" }; - -verify.navigationItemsListCount(0, notFoundSearchValue, "exact"); -verify.navigationItemsListCount(0, notFoundSearchValue, "prefix"); -verify.navigationItemsListCount(0, notFoundSearchValue, "substring"); \ No newline at end of file +verify.navigateTo( + { + pattern: "Horizon", + expected: [ + { ...horizon, isCaseSensitive: false }, + { ...origin, matchKind: "substring" }, + ], + }, + { + pattern: "horizon", + expected: [ + horizon, + { ...origin, matchKind: "substring", isCaseSensitive: false }, + ], + }, + { + pattern: "Distance", + expected: [ + { name: "distanceFromOrigin", matchKind: "prefix", isCaseSensitive: false, kind: "getter", range: r1, containerName: "Point", containerKind: "class" }, + { name: "distanceLocal", matchKind: "prefix", isCaseSensitive: false, kind: "var", range: r2, containerName: "distanceFromOrigin", containerKind: "getter" }, + { name: "IDistance", matchKind: "substring", kind: "interface", range: r4 }, + ], + }, + { + pattern: "INITIATED", + expected: [ + { name: "INITIATED123", matchKind: "prefix", kind: "property", range: r5, containerName: "IDistance", containerKind: "interface" }, + ], + }, + { + pattern: "mPointThatIJustInitiated wrongKeyWord", + expected: [ + { name: "myPointThatIJustInitiated", matchKind: "camelCase", kind: "var", range: r3 } + ], + }, +); diff --git a/tests/cases/fourslash/quickInfoMeaning.ts b/tests/cases/fourslash/quickInfoMeaning.ts index f50675ba393..6d5fa3fd964 100644 --- a/tests/cases/fourslash/quickInfoMeaning.ts +++ b/tests/cases/fourslash/quickInfoMeaning.ts @@ -6,23 +6,29 @@ // goToDefinition should work the same way. // @Filename: foo.d.ts -////declare const /*foo_value_declaration*/foo: number; -////declare module "foo_module" { +////declare const [|/*foo_value_declaration*/foo: number|]; +////[|declare module "foo_module" { //// interface /*foo_type_declaration*/I { x: number; y: number } //// export = I; -////} +////}|] // @Filename: foo_user.ts /////// -////import foo = require("foo_module"); +////[|import foo = require("foo_module");|] ////const x = foo/*foo_value*/; ////const i: foo/*foo_type*/ = { x: 1, y: 2 }; verify.noErrors(); -verify.navigationItemsListCount(2, "foo", "exact"); -verify.navigationItemsListContains("foo", "alias", "foo", "exact"); -verify.navigationItemsListContains("foo", "const", "foo", "exact"); +const [r0, r1, r2] = test.ranges(); +verify.navigateTo({ + pattern: "foo", + expected: [ + { name: "foo", kind: "const", kindModifiers: "declare", range: r0 }, + { name: "foo", kind: "alias", range: r2 }, + { name: "foo_module", matchKind: "prefix", kind: "module", kindModifiers: "declare", range: r1 }, + ], +}); goTo.marker("foo_value"); verify.quickInfoIs("const foo: number"); @@ -37,21 +43,28 @@ verify.goToDefinitionIs("foo_type_declaration"); // @Filename: bar.d.ts -////declare interface /*bar_type_declaration*/bar { x: number; y: number } -////declare module "bar_module" { +////[|declare interface /*bar_type_declaration*/bar { x: number; y: number }|] +////[|declare module "bar_module" { //// const /*bar_value_declaration*/x: number; //// export = x; -////} +////}|] // @Filename: bar_user.ts /////// -////import bar = require("bar_module"); +////[|import bar = require("bar_module");|] ////const x = bar/*bar_value*/; ////const i: bar/*bar_type*/ = { x: 1, y: 2 }; -verify.navigationItemsListCount(2, "bar", "exact"); -verify.navigationItemsListContains("bar", "alias", "bar", "exact"); -verify.navigationItemsListContains("bar", "interface", "bar", "exact"); +const [ , , , r3, r4, r5] = test.ranges(); + +verify.navigateTo({ + pattern: "bar", + expected: [ + { name: "bar", kind: "interface", kindModifiers: "declare", range: r3 }, + { name: "bar", kind: "alias", range: r5 }, + { name: "bar_module", matchKind: "prefix", kind: "module", kindModifiers: "declare", range: r4 }, + ], +}); goTo.marker("bar_value"); verify.quickInfoIs("(alias) const bar: number\nimport bar = require(\"bar_module\")"); diff --git a/tests/cases/fourslash/server/navto01.ts b/tests/cases/fourslash/server/navto01.ts index 1072c64494f..a8438faabd3 100644 --- a/tests/cases/fourslash/server/navto01.ts +++ b/tests/cases/fourslash/server/navto01.ts @@ -1,28 +1,24 @@ /// /////// Module -////{| "itemName": "MyShapes", "kind": "module", "parentName": "", "matchKind": "substring" |}module MyShapes { +////[|{| "name": "MyShapes", "kind": "module" |}module MyShapes { //// //// // Class -//// {| "itemName": "MyPoint", "kind": "class", "parentName": "MyShapes", "matchKind": "substring" |}export class MyPoint { +//// [|{| "name": "MyPoint", "kind": "class", "kindModifiers": "export", "containerName": "MyShapes", "containerKind": "module" |}export class MyPoint { //// // Instance member -//// {| "itemName": "MyoriginPointAttheHorizon", "kind": "property", "parentName": "MyPoint", "matchKind": "substring"|}private MyoriginPointAttheHorizon = 0.0; +//// [|{| "name": "MyoriginAttheHorizon", "kind": "property", "kindModifiers": "private", "containerName": "MyPoint", "containerKind": "class" |}private MyoriginAttheHorizon = 0.0;|] //// //// // Getter -//// {| "itemName": "MydistanceFromOrigin", "kind": "getter", "parentName": "MyPoint", "matchKind": "substring" |}get MydistanceFromOrigin(): number { return 0; } -//// -//// } -////} +//// [|{| "name": "MydistanceFromOrigin", "kind": "getter", "containerName": "MyPoint", "containerKind": "class" |}get MydistanceFromOrigin(): number { return 0; }|] +//// }|] +////}|] //// ////// Local variables -////{| "itemName": "myPointThatIJustInitiated", "kind": "var", "parentName": "", "matchKind": "substring"|}var myPointThatIJustInitiated = new Shapes.Point(); +////var [|{| "name": "myXyz", "kind": "var" |}myXyz = new Shapes.Point()|]; -//// Testing for substring matching of navigationItems -//var searchValue = "FromOrigin horizon INITIATED Shape Point"; - -test.markers().forEach((marker) => { - if (marker.data) { - var name = marker.data.itemName; - verify.navigationItemsListContains(name, marker.data.kind, name.substr(2), marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); \ No newline at end of file +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name.slice(2), + expected: [{ ...range.marker.data, range, matchKind: "substring" }], + }); +} diff --git a/tests/cases/fourslash/shims-pp/getNavigateToItems.ts b/tests/cases/fourslash/shims-pp/getNavigateToItems.ts index 5481f4295cb..0ffbf983ff1 100644 --- a/tests/cases/fourslash/shims-pp/getNavigateToItems.ts +++ b/tests/cases/fourslash/shims-pp/getNavigateToItems.ts @@ -1,27 +1,26 @@ -/// +/// /////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { +////[|{| "name": "Shapes", "kind": "module" |}module Shapes { //// //// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point { +//// [|{| "name": "Point", "kind": "class", "kindModifiers": "export", "containerName": "Shapes", "containerKind": "module" |}export class Point { //// // Instance member -//// {| "itemName": "origin", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private origin = 0.0; -//// -//// {| "itemName": "distFromZero", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private distFromZero = 0.0; +//// [|{| "name": "origin", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private origin = 0.0;|] +//// +//// [|{| "name": "distFromZero", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private distFromZero = 0.0;|] //// //// // Getter -//// {| "itemName": "distance", "kind": "getter", "parentName": "Point", "matchKind": "exact" |}get distance(): number { return 0; } -//// } -////} +//// [|{| "name": "distance", "kind": "getter", "containerName": "Point", "containerKind": "class" |}get distance(): number { return 0; }|] +//// }|] +////}|] //// ////// Local variables -////{| "itemName": "point", "kind": "var", "parentName": "", "matchKind": "exact"|}var point = new Shapes.Point(); +////var [|{| "name": "xyz", "kind": "var" |}xyz = new Shapes.Point()|]; -//// Testing for exact matching of navigationItems - -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationItemsListContains(marker.data.itemName, marker.data.kind, marker.data.itemName, marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +} diff --git a/tests/cases/fourslash/shims/getNavigateToItems.ts b/tests/cases/fourslash/shims/getNavigateToItems.ts index 5481f4295cb..0ffbf983ff1 100644 --- a/tests/cases/fourslash/shims/getNavigateToItems.ts +++ b/tests/cases/fourslash/shims/getNavigateToItems.ts @@ -1,27 +1,26 @@ -/// +/// /////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { +////[|{| "name": "Shapes", "kind": "module" |}module Shapes { //// //// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point { +//// [|{| "name": "Point", "kind": "class", "kindModifiers": "export", "containerName": "Shapes", "containerKind": "module" |}export class Point { //// // Instance member -//// {| "itemName": "origin", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private origin = 0.0; -//// -//// {| "itemName": "distFromZero", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private distFromZero = 0.0; +//// [|{| "name": "origin", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private origin = 0.0;|] +//// +//// [|{| "name": "distFromZero", "kind": "property", "kindModifiers": "private", "containerName": "Point", "containerKind": "class" |}private distFromZero = 0.0;|] //// //// // Getter -//// {| "itemName": "distance", "kind": "getter", "parentName": "Point", "matchKind": "exact" |}get distance(): number { return 0; } -//// } -////} +//// [|{| "name": "distance", "kind": "getter", "containerName": "Point", "containerKind": "class" |}get distance(): number { return 0; }|] +//// }|] +////}|] //// ////// Local variables -////{| "itemName": "point", "kind": "var", "parentName": "", "matchKind": "exact"|}var point = new Shapes.Point(); +////var [|{| "name": "xyz", "kind": "var" |}xyz = new Shapes.Point()|]; -//// Testing for exact matching of navigationItems - -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationItemsListContains(marker.data.itemName, marker.data.kind, marker.data.itemName, marker.data.matchKind, marker.fileName, marker.data.parentName); - } -}); +for (const range of test.ranges()) { + verify.navigateTo({ + pattern: range.marker.data.name, + expected: [{ ...range.marker.data, range }], + }); +}