mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Handle export declarations with module specifiers as well.
This commit is contained in:
parent
123e02974e
commit
a309b1dd67
@ -3014,17 +3014,17 @@ namespace ts {
|
||||
|
||||
function tryGetGlobalSymbols(): boolean {
|
||||
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
|
||||
let importClause: ImportClause;
|
||||
let namedImportsOrExports: NamedImportsOrExports;
|
||||
let jsxContainer: JsxOpeningLikeElement;
|
||||
|
||||
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
|
||||
return tryGetObjectLikeCompletionSymbols(objectLikeContainer);
|
||||
}
|
||||
|
||||
if (importClause = <ImportClause>getAncestor(contextToken, SyntaxKind.ImportClause)) {
|
||||
if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) {
|
||||
// cursor is in an import clause
|
||||
// try to show exported member for imported module
|
||||
return tryGetImportClauseCompletionSymbols(importClause);
|
||||
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
|
||||
}
|
||||
|
||||
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
|
||||
@ -3109,18 +3109,6 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function shouldShowCompletionsInImportsClause(node: Node): boolean {
|
||||
if (node) {
|
||||
// import {|
|
||||
// import {a,|
|
||||
if (node.kind === SyntaxKind.OpenBraceToken || node.kind === SyntaxKind.CommaToken) {
|
||||
return node.parent.kind === SyntaxKind.NamedImports;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isNewIdentifierDefinitionLocation(previousToken: Node): boolean {
|
||||
if (previousToken) {
|
||||
let containingNodeKind = previousToken.parent.kind;
|
||||
@ -3252,38 +3240,44 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregates relevant symbols for completion in import clauses; for instance,
|
||||
* Aggregates relevant symbols for completion in import clauses and export clauses
|
||||
* whose declarations have a module specifier; for instance, symbols will be aggregated for
|
||||
*
|
||||
* import { $ } from "moduleName";
|
||||
* import { | } from "moduleName";
|
||||
* export { a as foo, | } from "moduleName";
|
||||
*
|
||||
* but not for
|
||||
*
|
||||
* export { | };
|
||||
*
|
||||
* Relevant symbols are stored in the captured 'symbols' variable.
|
||||
*
|
||||
* @returns true if 'symbols' was successfully populated; false otherwise.
|
||||
*/
|
||||
function tryGetImportClauseCompletionSymbols(importClause: ImportClause): boolean {
|
||||
function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean {
|
||||
// cursor is in import clause
|
||||
// try to show exported member for imported module
|
||||
if (shouldShowCompletionsInImportsClause(contextToken)) {
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
|
||||
let importDeclaration = <ImportDeclaration>importClause.parent;
|
||||
Debug.assert(importDeclaration !== undefined && importDeclaration.kind === SyntaxKind.ImportDeclaration);
|
||||
let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ?
|
||||
SyntaxKind.ImportDeclaration :
|
||||
SyntaxKind.ExportDeclaration;
|
||||
let importOrExportDeclaration = <ImportDeclaration | ExportDeclaration>getAncestor(namedImportsOrExports, declarationKind);
|
||||
let moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
|
||||
|
||||
let exports: Symbol[];
|
||||
let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier);
|
||||
if (moduleSpecifierSymbol) {
|
||||
exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol);
|
||||
}
|
||||
|
||||
//let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
|
||||
symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray;
|
||||
if (!moduleSpecifier) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
isMemberCompletion = false;
|
||||
isNewIdentifierLocation = true;
|
||||
|
||||
let exports: Symbol[];
|
||||
let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier);
|
||||
if (moduleSpecifierSymbol) {
|
||||
exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol);
|
||||
}
|
||||
|
||||
symbols = exports ? filterModuleExports(exports, namedImportsOrExports) : emptyArray;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3307,6 +3301,26 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the containing list of named imports or exports of a context token,
|
||||
* on the condition that one exists and that the context implies completion should be given.
|
||||
*/
|
||||
function tryGetNamedImportsOrExportsForCompletion(contextToken: Node): NamedImportsOrExports {
|
||||
if (contextToken) {
|
||||
switch (contextToken.kind) {
|
||||
case SyntaxKind.OpenBraceToken: // import { |
|
||||
case SyntaxKind.CommaToken: // import { a as 0, |
|
||||
switch (contextToken.parent.kind) {
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamedExports:
|
||||
return <NamedImportsOrExports>contextToken.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
||||
if (contextToken) {
|
||||
let parent = contextToken.parent;
|
||||
@ -3452,25 +3466,18 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function filterModuleExports(exports: Symbol[], importDeclaration: ImportDeclaration): Symbol[] {
|
||||
function filterModuleExports(exports: Symbol[], namedImportsOrExports: NamedImportsOrExports): Symbol[] {
|
||||
let exisingImports: Map<boolean> = {};
|
||||
|
||||
if (!importDeclaration.importClause) {
|
||||
return exports;
|
||||
}
|
||||
|
||||
if (importDeclaration.importClause.namedBindings &&
|
||||
importDeclaration.importClause.namedBindings.kind === SyntaxKind.NamedImports) {
|
||||
|
||||
forEach((<NamedImports>importDeclaration.importClause.namedBindings).elements, el => {
|
||||
let name = el.propertyName || el.name;
|
||||
exisingImports[name.text] = true;
|
||||
});
|
||||
for (let element of namedImportsOrExports.elements) {
|
||||
let name = element.propertyName || element.name;
|
||||
exisingImports[name.text] = true;
|
||||
}
|
||||
|
||||
if (isEmpty(exisingImports)) {
|
||||
return exports;
|
||||
}
|
||||
|
||||
return filter(exports, e => !lookUp(exisingImports, e.name));
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user