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

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 ? ...`
};
}
}

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.:

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) {

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.:

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;

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;
}