@@ -118,6 +118,7 @@ namespace ts {
118
118
let thisParentContainer : Node ; // Container one level up
119
119
let blockScopeContainer : Node ;
120
120
let lastContainer : Node ;
121
+ let delayedTypedefs : { typedef : JSDocTypedefTag , container : Node , lastContainer : Node , blockScopeContainer : Node , parent : Node } [ ] ;
121
122
let seenThisKeyword : boolean ;
122
123
123
124
// state used by control flow analysis
@@ -176,6 +177,7 @@ namespace ts {
176
177
bind ( file ) ;
177
178
file . symbolCount = symbolCount ;
178
179
file . classifiableNames = classifiableNames ;
180
+ delayedBindJSDocTypedefTag ( ) ;
179
181
}
180
182
181
183
file = undefined ;
@@ -186,6 +188,7 @@ namespace ts {
186
188
thisParentContainer = undefined ;
187
189
blockScopeContainer = undefined ;
188
190
lastContainer = undefined ;
191
+ delayedTypedefs = undefined ;
189
192
seenThisKeyword = false ;
190
193
currentFlow = undefined ;
191
194
currentBreakTarget = undefined ;
@@ -450,8 +453,7 @@ namespace ts {
450
453
// and this case is specially handled. Module augmentations should only be merged with original module definition
451
454
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
452
455
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 ) ) {
455
457
if ( hasModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) {
456
458
return declareSymbol ( container . symbol . exports , container . symbol , node , symbolFlags , symbolExcludes ) ; // No local symbol for an unnamed default!
457
459
}
@@ -1727,7 +1729,7 @@ namespace ts {
1727
1729
declareModuleMember ( node , symbolFlags , symbolExcludes ) ;
1728
1730
break ;
1729
1731
case SyntaxKind . SourceFile :
1730
- if ( isExternalModule ( < SourceFile > container ) ) {
1732
+ if ( isExternalOrCommonJsModule ( < SourceFile > container ) ) {
1731
1733
declareModuleMember ( node , symbolFlags , symbolExcludes ) ;
1732
1734
break ;
1733
1735
}
@@ -1745,6 +1747,24 @@ namespace ts {
1745
1747
bindBlockScopedDeclaration ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
1746
1748
}
1747
1749
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
+
1748
1768
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
1749
1769
// check for reserved words used as identifiers in strict mode code.
1750
1770
function checkStrictModeIdentifier ( node : Identifier ) {
@@ -2194,7 +2214,7 @@ namespace ts {
2194
2214
case SyntaxKind . JSDocTypedefTag : {
2195
2215
const { fullName } = node as JSDocTypedefTag ;
2196
2216
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 } ) ;
2198
2218
}
2199
2219
break ;
2200
2220
}
@@ -2304,7 +2324,10 @@ namespace ts {
2304
2324
return s ;
2305
2325
} ) ;
2306
2326
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 ) ;
2308
2331
}
2309
2332
}
2310
2333
0 commit comments