@@ -70,7 +70,13 @@ namespace ts {
7070
7171 if ( value ) {
7272 value = visitNode ( value , visitor , isExpression ) ;
73- if ( needsValue ) {
73+
74+ if ( isIdentifier ( value ) && bindingOrAssignmentElementAssignsToName ( node , value . escapedText ) ) {
75+ // If the right-hand value of the assignment is also an assignment target then
76+ // we need to cache the right-hand value.
77+ value = ensureIdentifier ( flattenContext , value , /*reuseIdentifierExpressions*/ false , location ) ;
78+ }
79+ else if ( needsValue ) {
7480 // If the right-hand value of the destructuring assignment needs to be preserved (as
7581 // is the case when the destructuring assignment is part of a larger expression),
7682 // then we need to cache the right-hand value.
@@ -123,6 +129,27 @@ namespace ts {
123129 }
124130 }
125131
132+ function bindingOrAssignmentElementAssignsToName ( element : BindingOrAssignmentElement , escapedName : __String ) : boolean {
133+ const target = getTargetOfBindingOrAssignmentElement ( element ) ;
134+ if ( isBindingOrAssignmentPattern ( target ) ) {
135+ return bindingOrAssignmentPatternAssignsToName ( target , escapedName ) ;
136+ }
137+ else if ( isIdentifier ( target ) ) {
138+ return target . escapedText === escapedName ;
139+ }
140+ return false ;
141+ }
142+
143+ function bindingOrAssignmentPatternAssignsToName ( pattern : BindingOrAssignmentPattern , escapedName : __String ) : boolean {
144+ const elements = getElementsOfBindingOrAssignmentPattern ( pattern ) ;
145+ for ( const element of elements ) {
146+ if ( bindingOrAssignmentElementAssignsToName ( element , escapedName ) ) {
147+ return true ;
148+ }
149+ }
150+ return false ;
151+ }
152+
126153 /**
127154 * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
128155 *
@@ -157,6 +184,17 @@ namespace ts {
157184 createArrayBindingOrAssignmentElement : makeBindingElement ,
158185 visitor
159186 } ;
187+
188+ if ( isVariableDeclaration ( node ) ) {
189+ let initializer = getInitializerOfBindingOrAssignmentElement ( node ) ;
190+ if ( initializer && isIdentifier ( initializer ) && bindingOrAssignmentElementAssignsToName ( node , initializer . escapedText ) ) {
191+ // If the right-hand value of the assignment is also an assignment target then
192+ // we need to cache the right-hand value.
193+ initializer = ensureIdentifier ( flattenContext , initializer , /*reuseIdentifierExpressions*/ false , initializer ) ;
194+ node = updateVariableDeclaration ( node , node . name , node . type , initializer ) ;
195+ }
196+ }
197+
160198 flattenBindingOrAssignmentElement ( flattenContext , node , rval , node , skipInitializer ) ;
161199 if ( pendingExpressions ) {
162200 const temp = createTempVariable ( /*recordTempVariable*/ undefined ) ;
0 commit comments