@@ -3199,28 +3199,49 @@ module ts {
31993199 }
32003200 }
32013201
3202- function emitMemberAssignments ( node : ClassLikeDeclaration , staticFlag : NodeFlags ) {
3203- forEach ( node . members , member => {
3204- if ( member . kind === SyntaxKind . PropertyDeclaration && ( member . flags & NodeFlags . Static ) === staticFlag && ( < PropertyDeclaration > member ) . initializer ) {
3205- writeLine ( ) ;
3206- emitLeadingComments ( member ) ;
3207- emitStart ( member ) ;
3208- emitStart ( ( < PropertyDeclaration > member ) . name ) ;
3209- if ( staticFlag ) {
3210- emitDeclarationName ( node ) ;
3211- }
3212- else {
3213- write ( "this" ) ;
3214- }
3215- emitMemberAccessForPropertyName ( ( < PropertyDeclaration > member ) . name ) ;
3216- emitEnd ( ( < PropertyDeclaration > member ) . name ) ;
3217- write ( " = " ) ;
3218- emit ( ( < PropertyDeclaration > member ) . initializer ) ;
3219- write ( ";" ) ;
3220- emitEnd ( member ) ;
3221- emitTrailingComments ( member ) ;
3202+ function getInitializedProperties ( node : ClassLikeDeclaration , static : boolean ) {
3203+ let properties : PropertyDeclaration [ ] = [ ] ;
3204+ for ( let member of node . members ) {
3205+ if ( member . kind === SyntaxKind . PropertyDeclaration && static === ( ( member . flags & NodeFlags . Static ) !== 0 ) && ( < PropertyDeclaration > member ) . initializer ) {
3206+ properties . push ( < PropertyDeclaration > member ) ;
32223207 }
3223- } ) ;
3208+ }
3209+
3210+ return properties ;
3211+ }
3212+
3213+ function emitPropertyDeclarations ( node : ClassLikeDeclaration , properties : PropertyDeclaration [ ] ) {
3214+ for ( let property of properties ) {
3215+ emitPropertyDeclaration ( node , property ) ;
3216+ }
3217+ }
3218+
3219+ function emitPropertyDeclaration ( node : ClassLikeDeclaration , property : PropertyDeclaration , receiver ?: Identifier , isExpression ?: boolean ) {
3220+ writeLine ( ) ;
3221+ emitLeadingComments ( property ) ;
3222+ emitStart ( property ) ;
3223+ emitStart ( property . name ) ;
3224+ if ( receiver ) {
3225+ emit ( receiver ) ;
3226+ }
3227+ else {
3228+ if ( property . flags & NodeFlags . Static ) {
3229+ emitDeclarationName ( node ) ;
3230+ }
3231+ else {
3232+ write ( "this" ) ;
3233+ }
3234+ }
3235+ emitMemberAccessForPropertyName ( property . name ) ;
3236+ emitEnd ( property . name ) ;
3237+ write ( " = " ) ;
3238+ emit ( property . initializer ) ;
3239+ if ( ! isExpression ) {
3240+ write ( ";" ) ;
3241+ }
3242+
3243+ emitEnd ( property ) ;
3244+ emitTrailingComments ( property ) ;
32243245 }
32253246
32263247 function emitMemberFunctionsForES5AndLower ( node : ClassLikeDeclaration ) {
@@ -3338,6 +3359,14 @@ module ts {
33383359 tempVariables = undefined ;
33393360 tempParameters = undefined ;
33403361
3362+ emitConstructorWorker ( node , baseTypeElement ) ;
3363+
3364+ tempFlags = saveTempFlags ;
3365+ tempVariables = saveTempVariables ;
3366+ tempParameters = saveTempParameters ;
3367+ }
3368+
3369+ function emitConstructorWorker ( node : ClassLikeDeclaration , baseTypeElement : HeritageClauseElement ) {
33413370 // Check if we have property assignment inside class declaration.
33423371 // If there is property assignment, we need to emit constructor whether users define it or not
33433372 // If there is no property assignment, we can omit constructor if users do not define it
@@ -3425,7 +3454,7 @@ module ts {
34253454 emitEnd ( baseTypeElement ) ;
34263455 }
34273456 }
3428- emitMemberAssignments ( node , /*staticFlag*/ 0 ) ;
3457+ emitPropertyDeclarations ( node , getInitializedProperties ( node , /*static:*/ false ) ) ;
34293458 if ( ctor ) {
34303459 var statements : Node [ ] = ( < Block > ctor . body ) . statements ;
34313460 if ( superCall ) {
@@ -3445,10 +3474,6 @@ module ts {
34453474 if ( ctor ) {
34463475 emitTrailingComments ( ctor ) ;
34473476 }
3448-
3449- tempFlags = saveTempFlags ;
3450- tempVariables = saveTempVariables ;
3451- tempParameters = saveTempParameters ;
34523477 }
34533478
34543479 function emitClassExpression ( node : ClassExpression ) {
@@ -3540,6 +3565,29 @@ module ts {
35403565 }
35413566 }
35423567
3568+ // If the class has static properties, and it's a class expression, then we'll need
3569+ // to specialize the emit a bit. for a class expression of the form:
3570+ //
3571+ // class C { static a = 1; static b = 2; ... }
3572+ //
3573+ // We'll emit:
3574+ //
3575+ // (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp)
3576+ //
3577+ // This keeps the expression as an expression, while ensuring that the static parts
3578+ // of it have been initialized by the time it is used.
3579+ let staticProperties = getInitializedProperties ( node , /*static:*/ true ) ;
3580+ let isClassExpressionWithStaticProperties = staticProperties . length > 0 && node . kind === SyntaxKind . ClassExpression ;
3581+ let tempVariable : Identifier ;
3582+
3583+ if ( isClassExpressionWithStaticProperties ) {
3584+ tempVariable = createAndRecordTempVariable ( TempFlags . Auto ) ;
3585+ write ( "(" ) ;
3586+ increaseIndent ( ) ;
3587+ emit ( tempVariable ) ;
3588+ write ( " = " )
3589+ }
3590+
35433591 write ( "class" ) ;
35443592
35453593 // check if this is an "export default class" as it may not have a name. Do not emit the name if the class is decorated.
@@ -3590,9 +3638,24 @@ module ts {
35903638 // From ES6 specification:
35913639 // HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
35923640 // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
3593- writeLine ( ) ;
3594- emitMemberAssignments ( node , NodeFlags . Static ) ;
3595- emitDecoratorsOfClass ( node ) ;
3641+
3642+ if ( isClassExpressionWithStaticProperties ) {
3643+ for ( var property of staticProperties ) {
3644+ write ( "," ) ;
3645+ writeLine ( ) ;
3646+ emitPropertyDeclaration ( node , property , /*receiver:*/ tempVariable , /*isExpression:*/ true ) ;
3647+ }
3648+ write ( "," ) ;
3649+ writeLine ( ) ;
3650+ emit ( tempVariable ) ;
3651+ decreaseIndent ( ) ;
3652+ write ( ")" ) ;
3653+ }
3654+ else {
3655+ writeLine ( ) ;
3656+ emitPropertyDeclarations ( node , staticProperties ) ;
3657+ emitDecoratorsOfClass ( node ) ;
3658+ }
35963659
35973660 // If this is an exported class, but not on the top level (i.e. on an internal
35983661 // module), export it
@@ -3648,7 +3711,7 @@ module ts {
36483711 writeLine ( ) ;
36493712 emitConstructor ( node , baseTypeNode ) ;
36503713 emitMemberFunctionsForES5AndLower ( node ) ;
3651- emitMemberAssignments ( node , NodeFlags . Static ) ;
3714+ emitPropertyDeclarations ( node , getInitializedProperties ( node , /*static:*/ true ) ) ;
36523715 writeLine ( ) ;
36533716 emitDecoratorsOfClass ( node ) ;
36543717 writeLine ( ) ;
0 commit comments