mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Merge pull request #13446 from Microsoft/export_equals_completion
Include properties of an `export =` value in import completions.
This commit is contained in:
@@ -108,6 +108,7 @@ namespace ts {
|
||||
getAliasedSymbol: resolveAlias,
|
||||
getEmitResolver,
|
||||
getExportsOfModule: getExportsOfModuleAsArray,
|
||||
getExportsAndPropertiesOfModule,
|
||||
getAmbientModules,
|
||||
getJsxElementAttributesType,
|
||||
getJsxIntrinsicTagNames,
|
||||
@@ -1527,6 +1528,15 @@ namespace ts {
|
||||
return symbolsToArray(getExportsOfModule(moduleSymbol));
|
||||
}
|
||||
|
||||
function getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[] {
|
||||
const exports = getExportsOfModuleAsArray(moduleSymbol);
|
||||
const exportEquals = resolveExternalModuleSymbol(moduleSymbol);
|
||||
if (exportEquals !== moduleSymbol) {
|
||||
addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
|
||||
function tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined {
|
||||
const symbolTable = getExportsOfModule(moduleSymbol);
|
||||
if (symbolTable) {
|
||||
|
||||
@@ -2370,6 +2370,8 @@ namespace ts {
|
||||
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type;
|
||||
getJsxIntrinsicTagNames(): Symbol[];
|
||||
|
||||
@@ -425,8 +425,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private raiseError(message: string) {
|
||||
message = this.messageAtLastKnownMarker(message);
|
||||
throw new Error(message);
|
||||
throw new Error(this.messageAtLastKnownMarker(message));
|
||||
}
|
||||
|
||||
private messageAtLastKnownMarker(message: string) {
|
||||
@@ -723,6 +722,27 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCompletionsAt(markerName: string, expected: string[]) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const actualCompletions = this.getCompletionListAtCaret();
|
||||
if (!actualCompletions) {
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
|
||||
}
|
||||
|
||||
const actual = actualCompletions.entries;
|
||||
|
||||
if (actual.length !== expected.length) {
|
||||
this.raiseError(`Expected ${expected.length} completions, got ${actual.map(a => a.name)}.`);
|
||||
}
|
||||
|
||||
ts.zipWith(actual, expected, (completion, expectedCompletion, index) => {
|
||||
if (completion.name !== expectedCompletion) {
|
||||
this.raiseError(`Expected completion at index ${index} to be ${expectedCompletion}, got ${completion.name}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
if (completions) {
|
||||
@@ -3166,6 +3186,10 @@ namespace FourSlashInterface {
|
||||
super(state);
|
||||
}
|
||||
|
||||
public completionsAt(markerName: string, completions: string[]) {
|
||||
this.state.verifyCompletionsAt(markerName, completions);
|
||||
}
|
||||
|
||||
public quickInfoIs(expectedText: string, expectedDocumentation?: string) {
|
||||
this.state.verifyQuickInfoString(expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
@@ -1318,14 +1318,14 @@ namespace ts.Completions {
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
|
||||
let exports: Symbol[];
|
||||
const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier);
|
||||
if (moduleSpecifierSymbol) {
|
||||
exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol);
|
||||
const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier);
|
||||
if (!moduleSpecifierSymbol) {
|
||||
symbols = emptyArray;
|
||||
return true;
|
||||
}
|
||||
|
||||
symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray;
|
||||
|
||||
const exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
|
||||
symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
16
tests/cases/fourslash/completionListForExportEquals.ts
Normal file
16
tests/cases/fourslash/completionListForExportEquals.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
///<reference path="fourslash.ts"/>
|
||||
|
||||
// @Filename: /node_modules/foo/index.d.ts
|
||||
////export = Foo;
|
||||
////declare var Foo: Foo.Static;
|
||||
////declare namespace Foo {
|
||||
//// interface Static {
|
||||
//// foo(): void;
|
||||
//// }
|
||||
////}
|
||||
|
||||
// @Filename: /a.ts
|
||||
////import { /**/ } from "foo";
|
||||
|
||||
verify.completionsAt("", ["Static", "foo"]);
|
||||
14
tests/cases/fourslash/completionListForExportEquals2.ts
Normal file
14
tests/cases/fourslash/completionListForExportEquals2.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
///<reference path="fourslash.ts"/>
|
||||
|
||||
// @Filename: /node_modules/foo/index.d.ts
|
||||
////export = Foo;
|
||||
////interface Foo { bar: number; }
|
||||
////declare namespace Foo {
|
||||
//// interface Static {}
|
||||
////}
|
||||
|
||||
// @Filename: /a.ts
|
||||
////import { /**/ } from "foo";
|
||||
|
||||
verify.completionsAt("", ["Static"]);
|
||||
@@ -11,10 +11,7 @@
|
||||
// @Filename: app.ts
|
||||
////import {/*1*/} from './foo';
|
||||
|
||||
goTo.marker('1');
|
||||
verify.completionListContains('prop1');
|
||||
verify.completionListContains('prop2');
|
||||
verify.not.completionListContains('Foo');
|
||||
verify.completionsAt("1", ["prototype", "prop1", "prop2"]);
|
||||
verify.numberOfErrorsInCurrentFile(0);
|
||||
goTo.marker('2');
|
||||
verify.numberOfErrorsInCurrentFile(0);
|
||||
|
||||
@@ -138,6 +138,7 @@ declare namespace FourSlashInterface {
|
||||
class verify extends verifyNegatable {
|
||||
assertHasRanges(ranges: Range[]): void;
|
||||
caretAtMarker(markerName?: string): void;
|
||||
completionsAt(markerName: string, completions: string[]): void;
|
||||
indentationIs(numberOfSpaces: number): void;
|
||||
indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: ts.IndentStyle, baseIndentSize?: number): void;
|
||||
textAtCaretIs(text: string): void;
|
||||
|
||||
Reference in New Issue
Block a user