@@ -236,8 +236,9 @@ namespace ts {
236
236
if ( symbolFlags & SymbolFlags . Value ) {
237
237
const { valueDeclaration } = symbol ;
238
238
if ( ! valueDeclaration ||
239
+ ( isAssignmentDeclaration ( valueDeclaration ) && ! isAssignmentDeclaration ( node ) ) ||
239
240
( valueDeclaration . kind !== node . kind && isEffectiveModuleDeclaration ( valueDeclaration ) ) ) {
240
- // other kinds of value declarations take precedence over modules
241
+ // other kinds of value declarations take precedence over modules and assignment declarations
241
242
symbol . valueDeclaration = node ;
242
243
}
243
244
}
@@ -373,7 +374,8 @@ namespace ts {
373
374
// prototype symbols like methods.
374
375
symbolTable . set ( name , symbol = createSymbol ( SymbolFlags . None , name ) ) ;
375
376
}
376
- else {
377
+ else if ( ! ( includes & SymbolFlags . Variable && symbol . flags & SymbolFlags . JSContainer ) ) {
378
+ // JSContainers are allowed to merge with variables, no matter what other flags they have.
377
379
if ( isNamedDeclaration ( node ) ) {
378
380
node . name . parent = node ;
379
381
}
@@ -733,6 +735,8 @@ namespace ts {
733
735
return isNarrowingBinaryExpression ( < BinaryExpression > expr ) ;
734
736
case SyntaxKind . PrefixUnaryExpression :
735
737
return ( < PrefixUnaryExpression > expr ) . operator === SyntaxKind . ExclamationToken && isNarrowingExpression ( ( < PrefixUnaryExpression > expr ) . operand ) ;
738
+ case SyntaxKind . TypeOfExpression :
739
+ return isNarrowingExpression ( ( < TypeOfExpression > expr ) . expression ) ;
736
740
}
737
741
return false ;
738
742
}
@@ -1729,10 +1733,6 @@ namespace ts {
1729
1733
}
1730
1734
}
1731
1735
1732
- function bindBlockScopedVariableDeclaration ( node : Declaration ) {
1733
- bindBlockScopedDeclaration ( node , SymbolFlags . BlockScopedVariable , SymbolFlags . BlockScopedVariableExcludes ) ;
1734
- }
1735
-
1736
1736
function delayedBindJSDocTypedefTag ( ) {
1737
1737
if ( ! delayedTypeAliases ) {
1738
1738
return ;
@@ -2078,8 +2078,8 @@ namespace ts {
2078
2078
if ( isInJavaScriptFile ( node ) &&
2079
2079
file . commonJsModuleIndicator &&
2080
2080
isModuleExportsPropertyAccessExpression ( node as PropertyAccessExpression ) &&
2081
- ! lookupSymbolForNameWorker ( container , "module" as __String ) ) {
2082
- declareSymbol ( container . locals ! , /*parent*/ undefined , ( node as PropertyAccessExpression ) . expression as Identifier ,
2081
+ ! lookupSymbolForNameWorker ( blockScopeContainer , "module" as __String ) ) {
2082
+ declareSymbol ( file . locals ! , /*parent*/ undefined , ( node as PropertyAccessExpression ) . expression as Identifier ,
2083
2083
SymbolFlags . FunctionScopedVariable | SymbolFlags . ModuleExports , SymbolFlags . FunctionScopedVariableExcludes ) ;
2084
2084
}
2085
2085
break ;
@@ -2510,11 +2510,10 @@ namespace ts {
2510
2510
2511
2511
function bindPropertyAssignment ( name : EntityNameExpression , propertyAccess : PropertyAccessEntityNameExpression , isPrototypeProperty : boolean ) {
2512
2512
let namespaceSymbol = lookupSymbolForPropertyAccess ( name ) ;
2513
- const isToplevelNamespaceableInitializer = isBinaryExpression ( propertyAccess . parent )
2514
- ? getParentOfBinaryExpression ( propertyAccess . parent ) . parent . kind === SyntaxKind . SourceFile &&
2515
- ! ! getJavascriptInitializer ( getInitializerOfBinaryExpression ( propertyAccess . parent ) , isPrototypeAccess ( propertyAccess . parent . left ) )
2513
+ const isToplevel = isBinaryExpression ( propertyAccess . parent )
2514
+ ? getParentOfBinaryExpression ( propertyAccess . parent ) . parent . kind === SyntaxKind . SourceFile
2516
2515
: propertyAccess . parent . parent . kind === SyntaxKind . SourceFile ;
2517
- if ( ! isPrototypeProperty && ( ! namespaceSymbol || ! ( namespaceSymbol . flags & SymbolFlags . Namespace ) ) && isToplevelNamespaceableInitializer ) {
2516
+ if ( ! isPrototypeProperty && ( ! namespaceSymbol || ! ( namespaceSymbol . flags & SymbolFlags . Namespace ) ) && isToplevel ) {
2518
2517
// make symbols or add declarations for intermediate containers
2519
2518
const flags = SymbolFlags . Module | SymbolFlags . JSContainer ;
2520
2519
const excludeFlags = SymbolFlags . ValueModuleExcludes & ~ SymbolFlags . JSContainer ;
@@ -2537,12 +2536,10 @@ namespace ts {
2537
2536
( namespaceSymbol . members || ( namespaceSymbol . members = createSymbolTable ( ) ) ) :
2538
2537
( namespaceSymbol . exports || ( namespaceSymbol . exports = createSymbolTable ( ) ) ) ;
2539
2538
2540
- // Declare the method/property
2541
- const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags . JSContainer : 0 ;
2542
2539
const isMethod = isFunctionLikeDeclaration ( getAssignedJavascriptInitializer ( propertyAccess ) ! ) ;
2543
- const symbolFlags = ( isMethod ? SymbolFlags . Method : SymbolFlags . Property ) | jsContainerFlag ;
2544
- const symbolExcludes = ( isMethod ? SymbolFlags . MethodExcludes : SymbolFlags . PropertyExcludes ) & ~ jsContainerFlag ;
2545
- declareSymbol ( symbolTable , namespaceSymbol , propertyAccess , symbolFlags , symbolExcludes ) ;
2540
+ const includes = isMethod ? SymbolFlags . Method : SymbolFlags . Property ;
2541
+ const excludes = isMethod ? SymbolFlags . MethodExcludes : SymbolFlags . PropertyExcludes ;
2542
+ declareSymbol ( symbolTable , namespaceSymbol , propertyAccess , includes | SymbolFlags . JSContainer , excludes & ~ SymbolFlags . JSContainer ) ;
2546
2543
}
2547
2544
2548
2545
/**
@@ -2573,7 +2570,7 @@ namespace ts {
2573
2570
return false ;
2574
2571
}
2575
2572
2576
- function getParentOfBinaryExpression ( expr : BinaryExpression ) {
2573
+ function getParentOfBinaryExpression ( expr : Node ) {
2577
2574
while ( isBinaryExpression ( expr . parent ) ) {
2578
2575
expr = expr . parent ;
2579
2576
}
@@ -2660,8 +2657,11 @@ namespace ts {
2660
2657
}
2661
2658
2662
2659
if ( ! isBindingPattern ( node . name ) ) {
2660
+ const isEnum = ! ! getJSDocEnumTag ( node ) ;
2661
+ const enumFlags = ( isEnum ? SymbolFlags . RegularEnum : SymbolFlags . None ) ;
2662
+ const enumExcludes = ( isEnum ? SymbolFlags . RegularEnumExcludes : SymbolFlags . None ) ;
2663
2663
if ( isBlockOrCatchScoped ( node ) ) {
2664
- bindBlockScopedVariableDeclaration ( node ) ;
2664
+ bindBlockScopedDeclaration ( node , SymbolFlags . BlockScopedVariable | enumFlags , SymbolFlags . BlockScopedVariableExcludes | enumExcludes ) ;
2665
2665
}
2666
2666
else if ( isParameterDeclaration ( node ) ) {
2667
2667
// It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
@@ -2676,7 +2676,7 @@ namespace ts {
2676
2676
declareSymbolAndAddToSymbolTable ( node , SymbolFlags . FunctionScopedVariable , SymbolFlags . ParameterExcludes ) ;
2677
2677
}
2678
2678
else {
2679
- declareSymbolAndAddToSymbolTable ( node , SymbolFlags . FunctionScopedVariable , SymbolFlags . FunctionScopedVariableExcludes ) ;
2679
+ declareSymbolAndAddToSymbolTable ( node , SymbolFlags . FunctionScopedVariable | enumFlags , SymbolFlags . FunctionScopedVariableExcludes | enumExcludes ) ;
2680
2680
}
2681
2681
}
2682
2682
}
@@ -2804,9 +2804,7 @@ namespace ts {
2804
2804
// report error on class declarations
2805
2805
node . kind === SyntaxKind . ClassDeclaration ||
2806
2806
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
2807
- ( node . kind === SyntaxKind . ModuleDeclaration && shouldReportErrorOnModuleDeclaration ( < ModuleDeclaration > node ) ) ||
2808
- // report error on regular enums and const enums if preserveConstEnums is set
2809
- ( isEnumDeclaration ( node ) && ( ! isEnumConst ( node ) || options . preserveConstEnums ) ) ;
2807
+ ( node . kind === SyntaxKind . ModuleDeclaration && shouldReportErrorOnModuleDeclaration ( < ModuleDeclaration > node ) ) ;
2810
2808
2811
2809
if ( reportError ) {
2812
2810
currentFlow = reportedUnreachableFlow ;
@@ -2851,7 +2849,7 @@ namespace ts {
2851
2849
// As opposed to a pure declaration like an `interface`
2852
2850
function isExecutableStatement ( s : Statement ) : boolean {
2853
2851
// Don't remove statements that can validly be used before they appear.
2854
- return ! isFunctionDeclaration ( s ) && ! isPurelyTypeDeclaration ( s ) &&
2852
+ return ! isFunctionDeclaration ( s ) && ! isPurelyTypeDeclaration ( s ) && ! isEnumDeclaration ( s ) &&
2855
2853
// `var x;` may declare a variable used above
2856
2854
! ( isVariableStatement ( s ) && ! ( getCombinedNodeFlags ( s ) & ( NodeFlags . Let | NodeFlags . Const ) ) && s . declarationList . declarations . some ( d => ! d . initializer ) ) ;
2857
2855
}
0 commit comments