@@ -118,6 +118,7 @@ namespace ts {
118118 let thisParentContainer : Node ; // Container one level up
119119 let blockScopeContainer : Node ;
120120 let lastContainer : Node ;
121+ let delayedTypedefs : { typedef : JSDocTypedefTag , container : Node , lastContainer : Node , blockScopeContainer : Node , parent : Node } [ ] ;
121122 let seenThisKeyword : boolean ;
122123
123124 // state used by control flow analysis
@@ -176,6 +177,7 @@ namespace ts {
176177 bind ( file ) ;
177178 file . symbolCount = symbolCount ;
178179 file . classifiableNames = classifiableNames ;
180+ delayedBindJSDocTypedefTag ( ) ;
179181 }
180182
181183 file = undefined ;
@@ -186,6 +188,7 @@ namespace ts {
186188 thisParentContainer = undefined ;
187189 blockScopeContainer = undefined ;
188190 lastContainer = undefined ;
191+ delayedTypedefs = undefined ;
189192 seenThisKeyword = false ;
190193 currentFlow = undefined ;
191194 currentBreakTarget = undefined ;
@@ -450,8 +453,7 @@ namespace ts {
450453 // and this case is specially handled. Module augmentations should only be merged with original module definition
451454 // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
452455 if ( node . kind === SyntaxKind . JSDocTypedefTag ) Debug . assert ( isInJavaScriptFile ( node ) ) ; // We shouldn't add symbols for JSDoc nodes if not in a JS file.
453- const isJSDocTypedefInJSDocNamespace = isJSDocTypedefTag ( node ) && node . name && node . name . kind === SyntaxKind . Identifier && node . name . isInJSDocNamespace ;
454- if ( ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) || isJSDocTypedefInJSDocNamespace ) {
456+ if ( ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) || isJSDocTypedefTag ( node ) ) {
455457 if ( hasModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) {
456458 return declareSymbol ( container . symbol . exports , container . symbol , node , symbolFlags , symbolExcludes ) ; // No local symbol for an unnamed default!
457459 }
@@ -1727,7 +1729,7 @@ namespace ts {
17271729 declareModuleMember ( node , symbolFlags , symbolExcludes ) ;
17281730 break ;
17291731 case SyntaxKind . SourceFile :
1730- if ( isExternalModule ( < SourceFile > container ) ) {
1732+ if ( isExternalOrCommonJsModule ( < SourceFile > container ) ) {
17311733 declareModuleMember ( node , symbolFlags , symbolExcludes ) ;
17321734 break ;
17331735 }
@@ -1745,6 +1747,24 @@ namespace ts {
17451747 bindBlockScopedDeclaration ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
17461748 }
17471749
1750+ function delayedBindJSDocTypedefTag ( ) {
1751+ if ( ! delayedTypedefs ) {
1752+ return ;
1753+ }
1754+ const saveContainer = container ;
1755+ const saveLastContainer = lastContainer ;
1756+ const saveBlockScopeContainer = blockScopeContainer ;
1757+ const saveParent = parent ;
1758+ for ( const delay of delayedTypedefs ) {
1759+ ( { container, lastContainer, blockScopeContainer, parent } = delay ) ;
1760+ bindBlockScopedDeclaration ( delay . typedef , SymbolFlags . TypeAlias , SymbolFlags . TypeAliasExcludes ) ;
1761+ }
1762+ container = saveContainer ;
1763+ lastContainer = saveLastContainer ;
1764+ blockScopeContainer = saveBlockScopeContainer ;
1765+ parent = saveParent ;
1766+ }
1767+
17481768 // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
17491769 // check for reserved words used as identifiers in strict mode code.
17501770 function checkStrictModeIdentifier ( node : Identifier ) {
@@ -2194,7 +2214,7 @@ namespace ts {
21942214 case SyntaxKind . JSDocTypedefTag : {
21952215 const { fullName } = node as JSDocTypedefTag ;
21962216 if ( ! fullName || fullName . kind === SyntaxKind . Identifier ) {
2197- return bindBlockScopedDeclaration ( < Declaration > node , SymbolFlags . TypeAlias , SymbolFlags . TypeAliasExcludes ) ;
2217+ ( delayedTypedefs || ( delayedTypedefs = [ ] ) ) . push ( { typedef : node as JSDocTypedefTag , container , lastContainer , blockScopeContainer , parent } ) ;
21982218 }
21992219 break ;
22002220 }
@@ -2304,7 +2324,10 @@ namespace ts {
23042324 return s ;
23052325 } ) ;
23062326 if ( symbol ) {
2307- declareSymbol ( symbol . exports , symbol , lhs , SymbolFlags . Property | SymbolFlags . ExportValue , SymbolFlags . None ) ;
2327+ const flags = isClassExpression ( node . right ) ?
2328+ SymbolFlags . Property | SymbolFlags . ExportValue | SymbolFlags . Class :
2329+ SymbolFlags . Property | SymbolFlags . ExportValue ;
2330+ declareSymbol ( symbol . exports , symbol , lhs , flags , SymbolFlags . None ) ;
23082331 }
23092332 }
23102333
0 commit comments