@@ -2403,6 +2403,19 @@ module ts {
24032403 getCompletionEntriesFromSymbols ( filteredMembers , activeCompletionSession ) ;
24042404 }
24052405 }
2406+ else if ( getAncestor ( previousToken , SyntaxKind . ImportClause ) ) {
2407+ // cursor is in import clause
2408+ // try to show exported member for imported module
2409+ isMemberCompletion = true ;
2410+ isNewIdentifierLocation = true ;
2411+ if ( canShowCompletionInImportsClause ( previousToken ) ) {
2412+ var importDeclaration = < ImportDeclaration > getAncestor ( previousToken , SyntaxKind . ImportDeclaration ) ;
2413+ Debug . assert ( importDeclaration !== undefined ) ;
2414+ var exports = typeInfoResolver . getExportsOfExternalModule ( importDeclaration ) ;
2415+ var filteredExports = filterModuleExports ( exports , importDeclaration ) ;
2416+ getCompletionEntriesFromSymbols ( filteredExports , activeCompletionSession ) ;
2417+ }
2418+ }
24062419 else {
24072420 // Get scope members
24082421 isMemberCompletion = false ;
@@ -2453,6 +2466,16 @@ module ts {
24532466 return result ;
24542467 }
24552468
2469+ function canShowCompletionInImportsClause ( node : Node ) : boolean {
2470+ // import {|
2471+ // import {a,|
2472+ if ( node . kind === SyntaxKind . OpenBraceToken || node . kind === SyntaxKind . CommaToken ) {
2473+ return node . parent . kind === SyntaxKind . NamedImports ;
2474+ }
2475+
2476+ return false ;
2477+ }
2478+
24562479 function isNewIdentifierDefinitionLocation ( previousToken : Node ) : boolean {
24572480 if ( previousToken ) {
24582481 var containingNodeKind = previousToken . parent . kind ;
@@ -2531,6 +2554,8 @@ module ts {
25312554 return false ;
25322555 }
25332556
2557+
2558+
25342559 function getContainingObjectLiteralApplicableForCompletion ( previousToken : Node ) : ObjectLiteralExpression {
25352560 // The locations in an object literal expression that are applicable for completion are property name definition locations.
25362561
@@ -2664,6 +2689,34 @@ module ts {
26642689 return false ;
26652690 }
26662691
2692+ function filterModuleExports ( exports : Symbol [ ] , importDeclaration : ImportDeclaration ) : Symbol [ ] {
2693+ var exisingImports : Map < boolean > = { } ;
2694+
2695+ if ( ! importDeclaration . importClause ) {
2696+ return exports ;
2697+ }
2698+
2699+ if ( importDeclaration . importClause . name ) {
2700+ exisingImports [ importDeclaration . importClause . name . text ] = true ;
2701+ }
2702+
2703+ if ( importDeclaration . importClause . namedBindings &&
2704+ importDeclaration . importClause . namedBindings . kind === SyntaxKind . NamedImports ) {
2705+
2706+ forEach ( ( < NamedImports > importDeclaration . importClause . namedBindings ) . elements , el => {
2707+ var name = el . propertyName || el . name ;
2708+ exisingImports [ name . text ] = true ;
2709+ } ) ;
2710+ }
2711+
2712+ if ( isEmpty ( exisingImports ) ) {
2713+ return exports ;
2714+ }
2715+ else {
2716+ return filter ( exports , e => ! lookUp ( exisingImports , e . name ) ) ;
2717+ }
2718+ }
2719+
26672720 function filterContextualMembersList ( contextualMemberSymbols : Symbol [ ] , existingMembers : Declaration [ ] ) : Symbol [ ] {
26682721 if ( ! existingMembers || existingMembers . length === 0 ) {
26692722 return contextualMemberSymbols ;
0 commit comments