@@ -490,11 +490,11 @@ namespace ts {
490490 // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
491491 if ( isJSDocTypeAlias ( node ) ) Debug . assert ( isInJSFile ( node ) ) ; // We shouldn't add symbols for JSDoc nodes if not in a JS file.
492492 if ( ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) || isJSDocTypeAlias ( node ) ) {
493- if ( hasModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) {
493+ if ( ! container . locals || ( hasModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) ) {
494494 return declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ; // No local symbol for an unnamed default!
495495 }
496496 const exportKind = symbolFlags & SymbolFlags . Value ? SymbolFlags . ExportValue : 0 ;
497- const local = declareSymbol ( container . locals ! , /*parent*/ undefined , node , exportKind , symbolExcludes ) ;
497+ const local = declareSymbol ( container . locals , /*parent*/ undefined , node , exportKind , symbolExcludes ) ;
498498 local . exportSymbol = declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ;
499499 node . localSymbol = local ;
500500 return local ;
@@ -1806,7 +1806,19 @@ namespace ts {
18061806 currentFlow = { flags : FlowFlags . Start } ;
18071807 parent = typeAlias ;
18081808 bind ( typeAlias . typeExpression ) ;
1809- if ( isJSDocEnumTag ( typeAlias ) || ! typeAlias . fullName || typeAlias . fullName . kind === SyntaxKind . Identifier ) {
1809+ const declName = getNameOfDeclaration ( typeAlias ) ;
1810+ if ( ( isJSDocEnumTag ( typeAlias ) || ! typeAlias . fullName ) && declName && isPropertyAccessEntityNameExpression ( declName . parent ) ) {
1811+ // typedef anchored to an A.B.C assignment - we need to bind into B's namespace under name C
1812+ const isTopLevel = isTopLevelNamespaceAssignment ( declName . parent ) ;
1813+ if ( isTopLevel ) {
1814+ bindPotentiallyMissingNamespaces ( file . symbol , declName . parent , isTopLevel , ! ! findAncestor ( declName , d => isPropertyAccessExpression ( d ) && d . name . escapedText === "prototype" ) ) ;
1815+ const oldContainer = container ;
1816+ container = isPropertyAccessExpression ( declName . parent . expression ) ? declName . parent . expression . name : declName . parent . expression ;
1817+ declareModuleMember ( typeAlias , SymbolFlags . TypeAlias , SymbolFlags . TypeAliasExcludes ) ;
1818+ container = oldContainer ;
1819+ }
1820+ }
1821+ else if ( isJSDocEnumTag ( typeAlias ) || ! typeAlias . fullName || typeAlias . fullName . kind === SyntaxKind . Identifier ) {
18101822 parent = typeAlias . parent ;
18111823 bindBlockScopedDeclaration ( typeAlias , SymbolFlags . TypeAlias , SymbolFlags . TypeAliasExcludes ) ;
18121824 }
@@ -2607,7 +2619,7 @@ namespace ts {
26072619 }
26082620
26092621 function bindPotentiallyMissingNamespaces ( namespaceSymbol : Symbol | undefined , entityName : EntityNameExpression , isToplevel : boolean , isPrototypeProperty : boolean ) {
2610- if ( isToplevel && ! isPrototypeProperty && ( ! namespaceSymbol || ! ( namespaceSymbol . flags & SymbolFlags . Namespace ) ) ) {
2622+ if ( isToplevel && ! isPrototypeProperty ) {
26112623 // make symbols or add declarations for intermediate containers
26122624 const flags = SymbolFlags . Module | SymbolFlags . Assignment ;
26132625 const excludeFlags = SymbolFlags . ValueModuleExcludes & ~ SymbolFlags . Assignment ;
@@ -2642,11 +2654,15 @@ namespace ts {
26422654 declareSymbol ( symbolTable , namespaceSymbol , declaration , includes | SymbolFlags . Assignment , excludes & ~ SymbolFlags . Assignment ) ;
26432655 }
26442656
2645- function bindPropertyAssignment ( name : EntityNameExpression , propertyAccess : PropertyAccessEntityNameExpression , isPrototypeProperty : boolean ) {
2646- let namespaceSymbol = lookupSymbolForPropertyAccess ( name ) ;
2647- const isToplevel = isBinaryExpression ( propertyAccess . parent )
2657+ function isTopLevelNamespaceAssignment ( propertyAccess : PropertyAccessEntityNameExpression ) {
2658+ return isBinaryExpression ( propertyAccess . parent )
26482659 ? getParentOfBinaryExpression ( propertyAccess . parent ) . parent . kind === SyntaxKind . SourceFile
26492660 : propertyAccess . parent . parent . kind === SyntaxKind . SourceFile ;
2661+ }
2662+
2663+ function bindPropertyAssignment ( name : EntityNameExpression , propertyAccess : PropertyAccessEntityNameExpression , isPrototypeProperty : boolean ) {
2664+ let namespaceSymbol = lookupSymbolForPropertyAccess ( name ) ;
2665+ const isToplevel = isTopLevelNamespaceAssignment ( propertyAccess ) ;
26502666 namespaceSymbol = bindPotentiallyMissingNamespaces ( namespaceSymbol , propertyAccess . expression , isToplevel , isPrototypeProperty ) ;
26512667 bindPotentiallyNewExpandoMemberToNamespace ( propertyAccess , namespaceSymbol , isPrototypeProperty ) ;
26522668 }
0 commit comments