@@ -3010,68 +3010,21 @@ namespace ts {
30103010 }
30113011
30123012 function tryGetGlobalSymbols ( ) : boolean {
3013- let objectLikeContainer = tryGetObjectLikeCompletionContainer ( contextToken ) ;
3014- let jsxContainer = tryGetContainingJsxElement ( contextToken ) ;
3015- if ( objectLikeContainer ) {
3016- // We're looking up possible property names from contextual/inferred/declared type.
3017- isMemberCompletion = true ;
3018-
3019- let typeForObject : Type ;
3020- let existingMembers : Declaration [ ] ;
3021-
3022- if ( objectLikeContainer . kind === SyntaxKind . ObjectLiteralExpression ) {
3023- // We are completing on contextual types, but may also include properties
3024- // other than those within the declared type.
3025- isNewIdentifierLocation = true ;
3026-
3027- typeForObject = typeChecker . getContextualType ( < ObjectLiteralExpression > objectLikeContainer ) ;
3028- existingMembers = ( < ObjectLiteralExpression > objectLikeContainer ) . properties ;
3029- }
3030- else if ( objectLikeContainer . kind === SyntaxKind . ObjectBindingPattern ) {
3031- // We are *only* completing on properties from the type being destructured.
3032- isNewIdentifierLocation = false ;
3033-
3034- typeForObject = typeChecker . getTypeAtLocation ( objectLikeContainer ) ;
3035- existingMembers = ( < BindingPattern > objectLikeContainer ) . elements ;
3036- }
3037- else {
3038- Debug . fail ( "Expected object literal or binding pattern, got " + objectLikeContainer . kind ) ;
3039- }
3040-
3041- if ( ! typeForObject ) {
3042- return false ;
3043- }
3013+ let objectLikeContainer : ObjectLiteralExpression | BindingPattern ;
3014+ let importClause : ImportClause ;
3015+ let jsxContainer : JsxOpeningLikeElement ;
30443016
3045- let typeMembers = typeChecker . getPropertiesOfType ( typeForObject ) ;
3046- if ( typeMembers && typeMembers . length > 0 ) {
3047- // Add filtered items to the completion list
3048- symbols = filterObjectMembersList ( typeMembers , existingMembers ) ;
3049- }
3050- return true ;
3017+ if ( objectLikeContainer = tryGetObjectLikeCompletionContainer ( contextToken ) ) {
3018+ return tryGetObjectLikeCompletionSymbols ( objectLikeContainer ) ;
30513019 }
3052- else if ( getAncestor ( contextToken , SyntaxKind . ImportClause ) ) {
3053- // cursor is in import clause
3054- // try to show exported member for imported module
3055- isMemberCompletion = true ;
3056- isNewIdentifierLocation = true ;
3057- if ( showCompletionsInImportsClause ( contextToken ) ) {
3058- let importDeclaration = < ImportDeclaration > getAncestor ( contextToken , SyntaxKind . ImportDeclaration ) ;
3059- Debug . assert ( importDeclaration !== undefined ) ;
3060-
3061- let exports : Symbol [ ] ;
3062- if ( importDeclaration . moduleSpecifier ) {
3063- let moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( importDeclaration . moduleSpecifier ) ;
3064- if ( moduleSpecifierSymbol ) {
3065- exports = typeChecker . getExportsOfModule ( moduleSpecifierSymbol ) ;
3066- }
3067- }
30683020
3069- //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
3070- symbols = exports ? filterModuleExports ( exports , importDeclaration ) : emptyArray ;
3071- }
3072- return true ;
3021+ if ( importClause = < ImportClause > getAncestor ( contextToken , SyntaxKind . ImportClause ) ) {
3022+ // cursor is in an import clause
3023+ // try to show exported member for imported module
3024+ return tryGetImportClauseCompletionSymbols ( importClause ) ;
30733025 }
3074- else if ( jsxContainer ) {
3026+
3027+ if ( jsxContainer = tryGetContainingJsxElement ( contextToken ) ) {
30753028 let attrsType : Type ;
30763029 if ( ( jsxContainer . kind === SyntaxKind . JsxSelfClosingElement ) || ( jsxContainer . kind === SyntaxKind . JsxOpeningElement ) ) {
30773030 // Cursor is inside a JSX self-closing element or opening element
@@ -3153,7 +3106,7 @@ namespace ts {
31533106 return result ;
31543107 }
31553108
3156- function showCompletionsInImportsClause ( node : Node ) : boolean {
3109+ function shouldShowCompletionsInImportsClause ( node : Node ) : boolean {
31573110 if ( node ) {
31583111 // import {|
31593112 // import {a,|
@@ -3251,6 +3204,86 @@ namespace ts {
32513204 return false ;
32523205 }
32533206
3207+ /**
3208+ * Aggregates relevant symbols for completion in object literals and object binding patterns.
3209+ * Relevant symbols are stored in the captured 'symbols' variable.
3210+ *
3211+ * @returns true if 'symbols' was successfully populated; false otherwise.
3212+ */
3213+ function tryGetObjectLikeCompletionSymbols ( objectLikeContainer : ObjectLiteralExpression | BindingPattern ) : boolean {
3214+ // We're looking up possible property names from contextual/inferred/declared type.
3215+ isMemberCompletion = true ;
3216+
3217+ let typeForObject : Type ;
3218+ let existingMembers : Declaration [ ] ;
3219+
3220+ if ( objectLikeContainer . kind === SyntaxKind . ObjectLiteralExpression ) {
3221+ // We are completing on contextual types, but may also include properties
3222+ // other than those within the declared type.
3223+ isNewIdentifierLocation = true ;
3224+
3225+ typeForObject = typeChecker . getContextualType ( < ObjectLiteralExpression > objectLikeContainer ) ;
3226+ existingMembers = ( < ObjectLiteralExpression > objectLikeContainer ) . properties ;
3227+ }
3228+ else if ( objectLikeContainer . kind === SyntaxKind . ObjectBindingPattern ) {
3229+ // We are *only* completing on properties from the type being destructured.
3230+ isNewIdentifierLocation = false ;
3231+
3232+ typeForObject = typeChecker . getTypeAtLocation ( objectLikeContainer ) ;
3233+ existingMembers = ( < BindingPattern > objectLikeContainer ) . elements ;
3234+ }
3235+ else {
3236+ Debug . fail ( "Expected object literal or binding pattern, got " + objectLikeContainer . kind ) ;
3237+ }
3238+
3239+ if ( ! typeForObject ) {
3240+ return false ;
3241+ }
3242+
3243+ let typeMembers = typeChecker . getPropertiesOfType ( typeForObject ) ;
3244+ if ( typeMembers && typeMembers . length > 0 ) {
3245+ // Add filtered items to the completion list
3246+ symbols = filterObjectMembersList ( typeMembers , existingMembers ) ;
3247+ }
3248+ return true ;
3249+ }
3250+
3251+ /**
3252+ * Aggregates relevant symbols for completion in import clauses; for instance,
3253+ *
3254+ * import { $ } from "moduleName";
3255+ *
3256+ * Relevant symbols are stored in the captured 'symbols' variable.
3257+ *
3258+ * @returns true if 'symbols' was successfully populated; false otherwise.
3259+ */
3260+ function tryGetImportClauseCompletionSymbols ( importClause : ImportClause ) : boolean {
3261+ // cursor is in import clause
3262+ // try to show exported member for imported module
3263+ if ( shouldShowCompletionsInImportsClause ( contextToken ) ) {
3264+ isMemberCompletion = true ;
3265+ isNewIdentifierLocation = false ;
3266+
3267+ let importDeclaration = < ImportDeclaration > importClause . parent ;
3268+ Debug . assert ( importDeclaration !== undefined && importDeclaration . kind === SyntaxKind . ImportDeclaration ) ;
3269+
3270+ let exports : Symbol [ ] ;
3271+ let moduleSpecifierSymbol = typeChecker . getSymbolAtLocation ( importDeclaration . moduleSpecifier ) ;
3272+ if ( moduleSpecifierSymbol ) {
3273+ exports = typeChecker . getExportsOfModule ( moduleSpecifierSymbol ) ;
3274+ }
3275+
3276+ //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
3277+ symbols = exports ? filterModuleExports ( exports , importDeclaration ) : emptyArray ;
3278+ }
3279+ else {
3280+ isMemberCompletion = false ;
3281+ isNewIdentifierLocation = true ;
3282+ }
3283+
3284+ return true ;
3285+ }
3286+
32543287 /**
32553288 * Returns the immediate owning object literal or binding pattern of a context token,
32563289 * on the condition that one exists and that the context implies completion should be given.
0 commit comments