@@ -15,7 +15,7 @@ namespace ts {
15
15
referenced : boolean ;
16
16
}
17
17
18
- export function getModuleInstanceState ( node : ModuleDeclaration , visited ?: Map < ModuleInstanceState | undefined > ) : ModuleInstanceState {
18
+ export function getModuleInstanceState ( node : ModuleDeclaration , visited ?: Map < number , ModuleInstanceState | undefined > ) : ModuleInstanceState {
19
19
if ( node . body && ! node . body . parent ) {
20
20
// getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already
21
21
setParent ( node . body , node ) ;
@@ -24,8 +24,8 @@ namespace ts {
24
24
return node . body ? getModuleInstanceStateCached ( node . body , visited ) : ModuleInstanceState . Instantiated ;
25
25
}
26
26
27
- function getModuleInstanceStateCached ( node : Node , visited = createMap < ModuleInstanceState | undefined > ( ) ) {
28
- const nodeId = "" + getNodeId ( node ) ;
27
+ function getModuleInstanceStateCached ( node : Node , visited = new Map < number , ModuleInstanceState | undefined > ( ) ) {
28
+ const nodeId = getNodeId ( node ) ;
29
29
if ( visited . has ( nodeId ) ) {
30
30
return visited . get ( nodeId ) || ModuleInstanceState . NonInstantiated ;
31
31
}
@@ -35,7 +35,7 @@ namespace ts {
35
35
return result ;
36
36
}
37
37
38
- function getModuleInstanceStateWorker ( node : Node , visited : Map < ModuleInstanceState | undefined > ) : ModuleInstanceState {
38
+ function getModuleInstanceStateWorker ( node : Node , visited : Map < number , ModuleInstanceState | undefined > ) : ModuleInstanceState {
39
39
// A module is uninstantiated if it contains only
40
40
switch ( node . kind ) {
41
41
// 1. interface declarations, type alias declarations
@@ -107,7 +107,7 @@ namespace ts {
107
107
return ModuleInstanceState . Instantiated ;
108
108
}
109
109
110
- function getModuleInstanceStateForAliasTarget ( specifier : ExportSpecifier , visited : Map < ModuleInstanceState | undefined > ) {
110
+ function getModuleInstanceStateForAliasTarget ( specifier : ExportSpecifier , visited : Map < number , ModuleInstanceState | undefined > ) {
111
111
const name = specifier . propertyName || specifier . name ;
112
112
let p : Node | undefined = specifier . parent ;
113
113
while ( p ) {
@@ -2109,20 +2109,39 @@ namespace ts {
2109
2109
}
2110
2110
2111
2111
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
2112
- // check for reserved words used as identifiers in strict mode code.
2113
- function checkStrictModeIdentifier ( node : Identifier ) {
2114
- if ( inStrictMode &&
2115
- node . originalKeywordKind ! >= SyntaxKind . FirstFutureReservedWord &&
2116
- node . originalKeywordKind ! <= SyntaxKind . LastFutureReservedWord &&
2117
- ! isIdentifierName ( node ) &&
2112
+ // check for reserved words used as identifiers in strict mode code, as well as `yield` or `await` in
2113
+ // [Yield] or [Await] contexts, respectively.
2114
+ function checkContextualIdentifier ( node : Identifier ) {
2115
+ // Report error only if there are no parse errors in file
2116
+ if ( ! file . parseDiagnostics . length &&
2118
2117
! ( node . flags & NodeFlags . Ambient ) &&
2119
- ! ( node . flags & NodeFlags . JSDoc ) ) {
2118
+ ! ( node . flags & NodeFlags . JSDoc ) &&
2119
+ ! isIdentifierName ( node ) ) {
2120
2120
2121
- // Report error only if there are no parse errors in file
2122
- if ( ! file . parseDiagnostics . length ) {
2121
+ // strict mode identifiers
2122
+ if ( inStrictMode &&
2123
+ node . originalKeywordKind ! >= SyntaxKind . FirstFutureReservedWord &&
2124
+ node . originalKeywordKind ! <= SyntaxKind . LastFutureReservedWord ) {
2123
2125
file . bindDiagnostics . push ( createDiagnosticForNode ( node ,
2124
2126
getStrictModeIdentifierMessage ( node ) , declarationNameToString ( node ) ) ) ;
2125
2127
}
2128
+ else if ( node . originalKeywordKind === SyntaxKind . AwaitKeyword ) {
2129
+ if ( isExternalModule ( file ) && isInTopLevelContext ( node ) ) {
2130
+ file . bindDiagnostics . push ( createDiagnosticForNode ( node ,
2131
+ Diagnostics . Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module ,
2132
+ declarationNameToString ( node ) ) ) ;
2133
+ }
2134
+ else if ( node . flags & NodeFlags . AwaitContext ) {
2135
+ file . bindDiagnostics . push ( createDiagnosticForNode ( node ,
2136
+ Diagnostics . Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here ,
2137
+ declarationNameToString ( node ) ) ) ;
2138
+ }
2139
+ }
2140
+ else if ( node . originalKeywordKind === SyntaxKind . YieldKeyword && node . flags & NodeFlags . YieldContext ) {
2141
+ file . bindDiagnostics . push ( createDiagnosticForNode ( node ,
2142
+ Diagnostics . Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here ,
2143
+ declarationNameToString ( node ) ) ) ;
2144
+ }
2126
2145
}
2127
2146
}
2128
2147
@@ -2423,7 +2442,7 @@ namespace ts {
2423
2442
if ( currentFlow && ( isExpression ( node ) || parent . kind === SyntaxKind . ShorthandPropertyAssignment ) ) {
2424
2443
node . flowNode = currentFlow ;
2425
2444
}
2426
- return checkStrictModeIdentifier ( < Identifier > node ) ;
2445
+ return checkContextualIdentifier ( < Identifier > node ) ;
2427
2446
case SyntaxKind . SuperKeyword :
2428
2447
node . flowNode = currentFlow ;
2429
2448
break ;
@@ -2865,8 +2884,7 @@ namespace ts {
2865
2884
2866
2885
function addLateBoundAssignmentDeclarationToSymbol ( node : BinaryExpression | DynamicNamedDeclaration , symbol : Symbol | undefined ) {
2867
2886
if ( symbol ) {
2868
- const members = symbol . assignmentDeclarationMembers || ( symbol . assignmentDeclarationMembers = createMap ( ) ) ;
2869
- members . set ( "" + getNodeId ( node ) , node ) ;
2887
+ ( symbol . assignmentDeclarationMembers || ( symbol . assignmentDeclarationMembers = new Map ( ) ) ) . set ( getNodeId ( node ) , node ) ;
2870
2888
}
2871
2889
}
2872
2890
0 commit comments