@@ -278,6 +278,16 @@ namespace ts {
278
278
Debug . assert ( isWellKnownSymbolSyntactically ( nameExpression ) ) ;
279
279
return getPropertyNameForKnownSymbolName ( idText ( ( < PropertyAccessExpression > nameExpression ) . name ) ) ;
280
280
}
281
+ if ( isPrivateName ( name ) ) {
282
+ // containingClass exists because private names only allowed inside classes
283
+ const containingClass = getContainingClass ( name . parent ) ;
284
+ if ( ! containingClass ) {
285
+ // we're in a case where there's a private name outside a class (invalid)
286
+ return undefined ;
287
+ }
288
+ const containingClassSymbol = containingClass . symbol ;
289
+ return getPropertyNameForPrivateNameDescription ( containingClassSymbol , name . escapedText ) ;
290
+ }
281
291
return isPropertyNameLiteral ( name ) ? getEscapedTextOfIdentifierOrLiteral ( name ) : undefined ;
282
292
}
283
293
switch ( node . kind ) {
@@ -334,6 +344,10 @@ namespace ts {
334
344
335
345
const isDefaultExport = hasModifier ( node , ModifierFlags . Default ) ;
336
346
347
+ // need this before getDeclarationName
348
+ if ( isNamedDeclaration ( node ) ) {
349
+ node . name . parent = node ;
350
+ }
337
351
// The exported symbol for an export default function/class node is always named "default"
338
352
const name = isDefaultExport && parent ? InternalSymbolName . Default : getDeclarationName ( node ) ;
339
353
@@ -386,11 +400,6 @@ namespace ts {
386
400
symbolTable . set ( name , symbol = createSymbol ( SymbolFlags . None , name ) ) ;
387
401
}
388
402
else if ( ! ( includes & SymbolFlags . Variable && symbol . flags & SymbolFlags . Assignment ) ) {
389
- // Assignment declarations are allowed to merge with variables, no matter what other flags they have.
390
- if ( isNamedDeclaration ( node ) ) {
391
- node . name . parent = node ;
392
- }
393
-
394
403
// Report errors every position with duplicate declaration
395
404
// Report errors on previous encountered declarations
396
405
let message = symbol . flags & SymbolFlags . BlockScopedVariable
@@ -1458,7 +1467,7 @@ namespace ts {
1458
1467
}
1459
1468
if ( node . expression . kind === SyntaxKind . PropertyAccessExpression ) {
1460
1469
const propertyAccess = < PropertyAccessExpression > node . expression ;
1461
- if ( isNarrowableOperand ( propertyAccess . expression ) && isPushOrUnshiftIdentifier ( propertyAccess . name ) ) {
1470
+ if ( isIdentifier ( propertyAccess . name ) && isNarrowableOperand ( propertyAccess . expression ) && isPushOrUnshiftIdentifier ( propertyAccess . name ) ) {
1462
1471
currentFlow = createFlowArrayMutation ( currentFlow , node ) ;
1463
1472
}
1464
1473
}
@@ -1855,6 +1864,18 @@ namespace ts {
1855
1864
return Diagnostics . Identifier_expected_0_is_a_reserved_word_in_strict_mode ;
1856
1865
}
1857
1866
1867
+ // The binder visits every node, so this is a good place to check for
1868
+ // the reserved private name (there is only one)
1869
+ function checkPrivateName ( node : PrivateName ) {
1870
+ if ( node . escapedText === "#constructor" ) {
1871
+ // Report error only if there are no parse errors in file
1872
+ if ( ! file . parseDiagnostics . length ) {
1873
+ file . bindDiagnostics . push ( createDiagnosticForNode ( node ,
1874
+ Diagnostics . constructor_is_a_reserved_word , declarationNameToString ( node ) ) ) ;
1875
+ }
1876
+ }
1877
+ }
1878
+
1858
1879
function checkStrictModeBinaryExpression ( node : BinaryExpression ) {
1859
1880
if ( inStrictMode && isLeftHandSideExpression ( node . left ) && isAssignmentOperator ( node . operatorToken . kind ) ) {
1860
1881
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
@@ -2127,6 +2148,8 @@ namespace ts {
2127
2148
node . flowNode = currentFlow ;
2128
2149
}
2129
2150
return checkStrictModeIdentifier ( < Identifier > node ) ;
2151
+ case SyntaxKind . PrivateName :
2152
+ return checkPrivateName ( node as PrivateName ) ;
2130
2153
case SyntaxKind . PropertyAccessExpression :
2131
2154
case SyntaxKind . ElementAccessExpression :
2132
2155
if ( currentFlow && isNarrowableReference ( < Expression > node ) ) {
@@ -2424,7 +2447,7 @@ namespace ts {
2424
2447
if ( ! setCommonJsModuleIndicator ( node ) ) {
2425
2448
return ;
2426
2449
}
2427
- const symbol = forEachIdentifierInEntityName ( node . arguments [ 0 ] , /*parent*/ undefined , ( id , symbol ) => {
2450
+ const symbol = forEachIdentifierOrPrivateNameInEntityName ( node . arguments [ 0 ] , /*parent*/ undefined , ( id , symbol ) => {
2428
2451
if ( symbol ) {
2429
2452
addDeclarationToSymbol ( symbol , id , SymbolFlags . Module | SymbolFlags . Assignment ) ;
2430
2453
}
@@ -2443,7 +2466,7 @@ namespace ts {
2443
2466
return ;
2444
2467
}
2445
2468
const lhs = node . left as PropertyAccessEntityNameExpression ;
2446
- const symbol = forEachIdentifierInEntityName ( lhs . expression , /*parent*/ undefined , ( id , symbol ) => {
2469
+ const symbol = forEachIdentifierOrPrivateNameInEntityName ( lhs . expression , /*parent*/ undefined , ( id , symbol ) => {
2447
2470
if ( symbol ) {
2448
2471
addDeclarationToSymbol ( symbol , id , SymbolFlags . Module | SymbolFlags . Assignment ) ;
2449
2472
}
@@ -2613,7 +2636,7 @@ namespace ts {
2613
2636
// make symbols or add declarations for intermediate containers
2614
2637
const flags = SymbolFlags . Module | SymbolFlags . Assignment ;
2615
2638
const excludeFlags = SymbolFlags . ValueModuleExcludes & ~ SymbolFlags . Assignment ;
2616
- namespaceSymbol = forEachIdentifierInEntityName ( entityName , namespaceSymbol , ( id , symbol , parent ) => {
2639
+ namespaceSymbol = forEachIdentifierOrPrivateNameInEntityName ( entityName , namespaceSymbol , ( id , symbol , parent ) => {
2617
2640
if ( symbol ) {
2618
2641
addDeclarationToSymbol ( symbol , id , flags ) ;
2619
2642
return symbol ;
@@ -2701,15 +2724,15 @@ namespace ts {
2701
2724
}
2702
2725
}
2703
2726
2704
- function forEachIdentifierInEntityName ( e : EntityNameExpression , parent : Symbol | undefined , action : ( e : Identifier , symbol : Symbol | undefined , parent : Symbol | undefined ) => Symbol | undefined ) : Symbol | undefined {
2727
+ function forEachIdentifierOrPrivateNameInEntityName ( e : EntityNameExpression , parent : Symbol | undefined , action : ( e : Identifier | PrivateName , symbol : Symbol | undefined , parent : Symbol | undefined ) => Symbol | undefined ) : Symbol | undefined {
2705
2728
if ( isExportsOrModuleExportsOrAlias ( file , e ) ) {
2706
2729
return file . symbol ;
2707
2730
}
2708
2731
else if ( isIdentifier ( e ) ) {
2709
2732
return action ( e , lookupSymbolForPropertyAccess ( e ) , parent ) ;
2710
2733
}
2711
2734
else {
2712
- const s = forEachIdentifierInEntityName ( e . expression , parent , action ) ;
2735
+ const s = forEachIdentifierOrPrivateNameInEntityName ( e . expression , parent , action ) ;
2713
2736
if ( ! s || ! s . exports ) return Debug . fail ( ) ;
2714
2737
return action ( e . name , s . exports . get ( e . name . escapedText ) , s ) ;
2715
2738
}
@@ -3231,8 +3254,7 @@ namespace ts {
3231
3254
// A ClassDeclaration is ES6 syntax.
3232
3255
transformFlags = subtreeFlags | TransformFlags . AssertES2015 ;
3233
3256
3234
- // A class with a parameter property assignment, property initializer, computed property name, or decorator is
3235
- // TypeScript syntax.
3257
+ // A class with a parameter property assignment or decorator is TypeScript syntax.
3236
3258
// An exported declaration may be TypeScript syntax, but is handled by the visitor
3237
3259
// for a namespace declaration.
3238
3260
if ( ( subtreeFlags & TransformFlags . ContainsTypeScriptClassSyntax )
@@ -3249,8 +3271,7 @@ namespace ts {
3249
3271
// A ClassExpression is ES6 syntax.
3250
3272
let transformFlags = subtreeFlags | TransformFlags . AssertES2015 ;
3251
3273
3252
- // A class with a parameter property assignment, property initializer, or decorator is
3253
- // TypeScript syntax.
3274
+ // A class with a parameter property assignment or decorator is TypeScript syntax.
3254
3275
if ( subtreeFlags & TransformFlags . ContainsTypeScriptClassSyntax
3255
3276
|| node . typeParameters ) {
3256
3277
transformFlags |= TransformFlags . AssertTypeScript ;
@@ -3340,7 +3361,6 @@ namespace ts {
3340
3361
|| hasModifier ( node , ModifierFlags . TypeScriptModifier )
3341
3362
|| node . typeParameters
3342
3363
|| node . type
3343
- || ( node . name && isComputedPropertyName ( node . name ) ) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly
3344
3364
|| ! node . body ) {
3345
3365
transformFlags |= TransformFlags . AssertTypeScript ;
3346
3366
}
@@ -3371,7 +3391,6 @@ namespace ts {
3371
3391
if ( node . decorators
3372
3392
|| hasModifier ( node , ModifierFlags . TypeScriptModifier )
3373
3393
|| node . type
3374
- || ( node . name && isComputedPropertyName ( node . name ) ) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly
3375
3394
|| ! node . body ) {
3376
3395
transformFlags |= TransformFlags . AssertTypeScript ;
3377
3396
}
@@ -3386,12 +3405,15 @@ namespace ts {
3386
3405
}
3387
3406
3388
3407
function computePropertyDeclaration ( node : PropertyDeclaration , subtreeFlags : TransformFlags ) {
3389
- // A PropertyDeclaration is TypeScript syntax.
3390
- let transformFlags = subtreeFlags | TransformFlags . AssertTypeScript ;
3408
+ let transformFlags = subtreeFlags ;
3409
+
3410
+ // Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax.
3411
+ if ( some ( node . decorators ) || hasModifier ( node , ModifierFlags . TypeScriptModifier ) || node . type ) {
3412
+ transformFlags |= TransformFlags . AssertTypeScript ;
3413
+ }
3391
3414
3392
- // If the PropertyDeclaration has an initializer or a computed name, we need to inform its ancestor
3393
- // so that it handle the transformation.
3394
- if ( node . initializer || isComputedPropertyName ( node . name ) ) {
3415
+ // Hoisted variables related to class properties should live within the TypeScript class wrapper.
3416
+ if ( isComputedPropertyName ( node . name ) || ( hasStaticModifier ( node ) && node . initializer ) ) {
3395
3417
transformFlags |= TransformFlags . ContainsTypeScriptClassSyntax ;
3396
3418
}
3397
3419
0 commit comments