More thoroughly test navigateTo (#25239)

* More thoroughly test navigateTo

* Fix #25233 and #25237

* Update API (#24966)
This commit is contained in:
Andy
2018-07-02 19:25:27 -07:00
committed by GitHub
parent c3b81b3e10
commit efc1b7df08
45 changed files with 658 additions and 510 deletions
+8 -7
View File
@@ -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;
+3 -3
View File
@@ -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),
}));
+33 -69
View File
@@ -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<FourSlashInterface.VerifyNavigateToOptions>): 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<ts.JSDocTagInfo>;
}
export interface VerifyNavigateToOptions {
readonly pattern: string;
readonly fileName?: string;
readonly expected: ReadonlyArray<ExpectedNavigateToItem>;
}
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> = T | ReadonlyArray<T>;
export interface VerifyCompletionListContainsOptions extends ts.UserPreferences {
+2 -2
View File
@@ -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').
+2 -3
View File
@@ -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;
}
+15 -18
View File
@@ -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<SourceFile>, 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<Declaration>, checker: TypeChecker, fileName: string, rawItems: Push<RawNavigateToItem>): 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<string> {
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 ? (<Identifier>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 ? ...`
};
}
}
+1 -1
View File
@@ -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.:
-2
View File
@@ -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) {
+3 -3
View File
@@ -633,7 +633,7 @@ namespace ts {
private computeNamedDeclarations(): Map<Declaration[]> {
const result = createMultiMap<Declaration>();
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.:
+2 -2
View File
@@ -78,7 +78,7 @@ namespace ts {
/* @internal */ scriptSnapshot: IScriptSnapshot | undefined;
/* @internal */ nameTable: UnderscoreEscapedMap<number> | undefined;
/* @internal */ getNamedDeclarations(): Map<Declaration[]>;
/* @internal */ getNamedDeclarations(): Map<ReadonlyArray<Declaration>>;
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;
+2 -1
View File
@@ -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;
}
@@ -9010,7 +9010,7 @@ export function Test2() {
const navtoRequest = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { file: bTs.path, searchValue: "fn" });
const navtoResponse = session.executeCommand(navtoRequest).response as protocol.NavtoResponse["body"];
assert.deepEqual(navtoResponse, [
assert.deepEqual<ReadonlyArray<protocol.NavtoItem> | 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",
}
+6 -4
View File
@@ -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<number> | undefined;
getNamedDeclarations(): Map<Declaration[]>;
getNamedDeclarations(): Map<ReadonlyArray<Declaration>>;
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
getLineEndOfPosition(pos: number): number;
getLineStarts(): ReadonlyArray<number>;
@@ -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;
+1 -1
View File
@@ -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;
+15 -24
View File
@@ -1,30 +1,21 @@
/// <reference path="fourslash.ts"/>
////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");
+2 -4
View File
@@ -1,7 +1,5 @@
/// <reference path="fourslash.ts" />
//// /**/declare function
////declare function
goTo.marker();
//verify there is no empty navigation item.
verify.navigationItemsListCount(0, "")
verify.navigateTo({ pattern: "", expected: [] });
+17 -2
View File
@@ -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<JSDocTagInfo>;
}
interface VerifyNavigateToOptions {
readonly pattern: string;
readonly fileName?: string;
readonly expected: ReadonlyArray<ExpectedNavigateToItem>;
}
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;
@@ -1,8 +1,18 @@
///<reference path="fourslash.ts" />
//// /**/
// @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 },
},
],
});
+10 -11
View File
@@ -1,16 +1,15 @@
/// <reference path="fourslash.ts" />
////{| "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);
});
for (const range of test.ranges()) {
verify.navigateTo({
pattern: range.marker.data.name,
expected: [{ ...range.marker.data, range }],
})
}
+16 -17
View File
@@ -1,20 +1,19 @@
/// <reference path="fourslash.ts" />
////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);
});
////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 }],
});
}
+23 -22
View File
@@ -1,25 +1,26 @@
/// <reference path="fourslash.ts" />
////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);
});
////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 }],
});
}
+9 -11
View File
@@ -1,16 +1,14 @@
/// <reference path="fourslash.ts" />
////{| "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);
});
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" }] },
);
+19 -12
View File
@@ -1,19 +1,26 @@
/// <reference path="fourslash.ts" />
// @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<FourSlashInterface.ExpectedNavigateToItem> = [{ name: "onResume", kind: "function", range: r0 }];
const bTs: ReadonlyArray<FourSlashInterface.ExpectedNavigateToItem> = [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 },
);
+9 -9
View File
@@ -1,14 +1,14 @@
/// <reference path="fourslash.ts" />
// @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 }] },
);
+19 -5
View File
@@ -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" }],
},
);
@@ -1,19 +1,27 @@
/// <reference path="fourslash.ts" />
// @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<FourSlashInterface.ExpectedNavigateToItem> = [
{ name: "hello", kind: "method", kindModifiers: "public", range: r0, containerName: "Greeter", containerKind: "class" },
];
const bTs: ReadonlyArray<FourSlashInterface.ExpectedNavigateToItem> = [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 },
);
@@ -1,7 +1,12 @@
/// <reference path="fourslash.ts" />
////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" },
],
});
@@ -1,3 +1,5 @@
/// <reference path="fourslash.ts"/>
////import *{} from 'foo';
verify.navigationTree({
@@ -1,20 +1,16 @@
/// <reference path="fourslash.ts"/>
////{| "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);
});
////[|{| "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 }],
});
}
@@ -1,27 +1,22 @@
/// <reference path="fourslash.ts"/>
/////// 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 }],
});
}
@@ -1,28 +1,50 @@
/// <reference path="fourslash.ts"/>
// @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");
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: [],
}
);
@@ -1,13 +1,20 @@
/// <reference path="fourslash.ts"/>
// @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" },
],
});
@@ -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],
},
);
@@ -1,12 +1,16 @@
/// <reference path="fourslash.ts"/>
////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" })),
});
@@ -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");
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" }],
}
);
@@ -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");
const [r0, r1, r2, r3] = test.ranges();
const overload1: ReadonlyArray<FourSlashInterface.ExpectedNavigateToItem> = [
{ name: "overload1", kind: "function", range: r0 },
];
const overload2: ReadonlyArray<FourSlashInterface.ExpectedNavigateToItem> = [
{ 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" })),
},
);
@@ -1,29 +1,23 @@
/// <reference path="fourslash.ts"/>
/////// 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" }],
});
}
@@ -1,32 +1,46 @@
/// <reference path="fourslash.ts"/>
// @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");
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: [],
},
);
@@ -1,20 +1,41 @@
/// <reference path="fourslash.ts"/>
// @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 }],
},
);
@@ -1,25 +1,24 @@
/// <reference path="fourslash.ts"/>
/////// 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);
}
});
for (const range of test.ranges()) {
verify.navigateTo({
pattern: range.marker.data.name.slice(2),
expected: [{ ...range.marker.data, range, matchKind: "substring" }],
})
}
@@ -1,35 +1,61 @@
/// <reference path="fourslash.ts"/>
// @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");
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 }
],
},
);
+27 -14
View File
@@ -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
///////<reference path="foo.d.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
///////<reference path="bar.d.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\")");
+13 -17
View File
@@ -1,28 +1,24 @@
/// <reference path="../fourslash.ts"/>
/////// 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);
}
});
for (const range of test.ranges()) {
verify.navigateTo({
pattern: range.marker.data.name.slice(2),
expected: [{ ...range.marker.data, range, matchKind: "substring" }],
});
}
@@ -1,27 +1,26 @@
/// <reference path="fourslash.ts"/>
/// <reference path="../fourslash.ts"/>
/////// 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 }],
});
}
@@ -1,27 +1,26 @@
/// <reference path="fourslash.ts"/>
/// <reference path="../fourslash.ts"/>
/////// 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 }],
});
}