def _buildInplaceAssignVariableNode(variable_ref, operator, expression, source_ref): assert variable_ref.isExpressionTargetVariableRef(), variable_ref inplace_node = makeExpressionOperationBinaryInplace( operator = operator, left = ExpressionVariableRef( variable_name = variable_ref.getVariableName(), source_ref = source_ref ), right = expression, source_ref = source_ref ) inplace_node.markAsInplaceSuspect() result = ( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = variable_ref.getVariableName(), source_ref = source_ref ), source = inplace_node, source_ref = source_ref ), ) return result
def _buildInplaceAssignAttributeNode( provider, lookup_source, attribute_name, tmp_variable1, tmp_variable2, operator, expression, source_ref, ): # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable=tmp_variable1, source=ExpressionAttributeLookup( source=lookup_source.makeClone(), attribute_name=attribute_name, source_ref=source_ref, ), source_ref=source_ref, ) # Second assign the in-place result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable=tmp_variable2, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) # Third, copy it back. copy_back_from_tmp = makeTryFinallyStatement( provider=provider, tried=StatementAssignmentAttribute( expression=lookup_source.makeClone(), attribute_name=attribute_name, source=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ), final=StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement( provider=provider, tried=(inplace_to_tmp, copy_back_from_tmp), final=StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref), source_ref=source_ref, ), )
def _buildInplaceAssignAttributeNode(provider, lookup_source, attribute_name, tmp_variable1, tmp_variable2, operator, expression, source_ref): # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable=tmp_variable1, source=ExpressionAttributeLookup(source=lookup_source.makeClone(), attribute_name=attribute_name, source_ref=source_ref), source_ref=source_ref) # Second assign the in-place result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable=tmp_variable2, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref) # Third, copy it over, if the reference values change, i.e. IsNot is true. copy_back_from_tmp = StatementConditional( condition=ExpressionComparisonIsNOT( left=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentAttribute( expression=lookup_source.makeClone(), attribute_name=attribute_name, source=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref) copy_back_from_tmp = makeTryFinallyStatement( provider=provider, tried=copy_back_from_tmp, final=StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement(provider=provider, tried=( inplace_to_tmp, copy_back_from_tmp, ), final=StatementReleaseVariable( variable=tmp_variable1, source_ref=source_ref), source_ref=source_ref))
def _buildInplaceAssignSubscriptNode( provider, subscribed, subscript, tmp_variable1, tmp_variable2, operator, expression, source_ref, ): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable( variable=tmp_variable1, source=subscribed, source_ref=source_ref ) # Second assign the subscript value to a temporary variable preserve_to_tmp2 = StatementAssignmentVariable( variable=tmp_variable2, source=subscript, source_ref=source_ref ) execute_in_place = StatementAssignmentSubscript( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), subscript=ExpressionTempVariableRef( variable=tmp_variable2, source_ref=source_ref ), source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), subscript=ExpressionTempVariableRef( variable=tmp_variable2, source_ref=source_ref ), source_ref=source_ref, ), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) # Note: No copy back is happening, for subscripts that is implied. return ( preserve_to_tmp1, makeTryFinallyStatement( provider=provider, tried=(preserve_to_tmp2, execute_in_place), final=( StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), ), source_ref=source_ref, ), )
def _buildInplaceAssignSubscriptNode( provider, subscribed, subscript, tmp_variable1, tmp_variable2, operator, expression, source_ref, ): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1, source=subscribed, source_ref=source_ref) # Second assign the subscript value to a temporary variable preserve_to_tmp2 = StatementAssignmentVariable(variable=tmp_variable2, source=subscript, source_ref=source_ref) execute_in_place = StatementAssignmentSubscript( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) # Note: No copy back is happening, for subscripts that is implied. return ( preserve_to_tmp1, makeTryFinallyStatement( provider=provider, tried=(preserve_to_tmp2, execute_in_place), final=( StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), ), source_ref=source_ref, ), )
def _buildInplaceAssignVariableNode(variable_name, operator, expression, source_ref): inplace_node = makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionVariableNameRef(variable_name=variable_name, source_ref=source_ref), right=expression, source_ref=source_ref) inplace_node.markAsInplaceSuspect() return (StatementAssignmentVariableName(variable_name=variable_name, source=inplace_node, source_ref=source_ref), )
def _buildInplaceAssignVariableNode( provider, variable_name, operator, expression, source_ref ): inplace_node = makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionVariableNameRef( provider=provider, variable_name=variable_name, source_ref=source_ref ), right=expression, source_ref=source_ref, ) inplace_node.markAsInplaceSuspect() return ( StatementAssignmentVariableName( provider=provider, variable_name=variable_name, source=inplace_node, source_ref=source_ref, ), )
def _buildInplaceAssignSliceNode( provider, lookup_source, lower, upper, tmp_variable1, tmp_variable2, tmp_variable3, tmp_variable4, operator, expression, source_ref, ): # Due to the 3 inputs, which we need to also put into temporary variables, # there are too many variables here, but they are needed. # pylint: disable=too-many-locals # First assign the target value, lower and upper to temporary variables. copy_to_tmp = StatementAssignmentVariable(variable=tmp_variable1, source=lookup_source, source_ref=source_ref) final_statements = [ StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref) ] statements = [] if lower is not None: statements.append( StatementAssignmentVariable(variable=tmp_variable2, source=lower, source_ref=source_ref)) final_statements.append( StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref)) lower_ref1 = ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref) lower_ref2 = ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref) else: assert tmp_variable2 is None lower_ref1 = lower_ref2 = None if upper is not None: statements.append( StatementAssignmentVariable(variable=tmp_variable3, source=upper, source_ref=source_ref)) final_statements.append( StatementReleaseVariable(variable=tmp_variable3, source_ref=source_ref)) upper_ref1 = ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref) upper_ref2 = ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref) else: assert tmp_variable3 is None upper_ref1 = upper_ref2 = None use_sliceobj = python_version >= 300 # Second assign the in-place result over the original value. if use_sliceobj: statements += ( StatementAssignmentVariable( variable=tmp_variable4, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), subscript=makeExpressionBuiltinSlice( start=lower_ref2, stop=upper_ref2, step=None, source_ref=source_ref, ), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_variable4, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable4, source_ref=source_ref), right=expression, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentSubscript( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=makeExpressionBuiltinSlice(start=lower_ref1, stop=upper_ref1, step=None, source_ref=source_ref), source=ExpressionTempVariableRef(variable=tmp_variable4, source_ref=source_ref), source_ref=source_ref, ), ) else: statements += ( StatementAssignmentVariable( variable=tmp_variable4, source=ExpressionSliceLookup( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), lower=lower_ref2, upper=upper_ref2, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_variable4, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable4, source_ref=source_ref), right=expression, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentSlice( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), lower=lower_ref1, upper=upper_ref1, source=ExpressionTempVariableRef(variable=tmp_variable4, source_ref=source_ref), source_ref=source_ref, ), ) final_statements.append( StatementReleaseVariable(variable=tmp_variable4, source_ref=source_ref)) return ( copy_to_tmp, makeTryFinallyStatement( provider=provider, tried=statements, final=final_statements, source_ref=source_ref, ), )
def _buildInplaceAssignSubscriptNode( provider, subscribed, subscript, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref, ): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1, source=subscribed, source_ref=source_ref) # Second assign the subscript value to a temporary variable statements = ( StatementAssignmentVariable(variable=tmp_variable2, source=subscript, source_ref=source_ref), StatementAssignmentVariable( variable=tmp_variable3, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_variable3, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref), right=expression, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentSubscript( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref), source_ref=source_ref, ), ) return ( preserve_to_tmp1, makeTryFinallyStatement( provider=provider, tried=statements, final=( StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable3, source_ref=source_ref), ), source_ref=source_ref, ), )
def onLeaveNode(self, node): if node.isStatementAssignmentVariableName(): variable_name = node.getVariableName() provider = node.provider # Classes always assign to locals dictionary except for closure # variables taken. if self._shouldUseLocalsDict(provider, variable_name): if node.subnode_source.isExpressionOperationInplace(): temp_scope = provider.allocateTempScope("class_inplace") tmp_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="value" ) statements = mergeStatements( statements=( StatementAssignmentVariable( variable=tmp_variable, source=node.subnode_source.getLeft(), source_ref=node.source_ref, ), makeTryFinallyStatement( provider=provider, tried=( StatementAssignmentVariable( variable=tmp_variable, source=makeExpressionOperationBinaryInplace( left=ExpressionTempVariableRef( variable=tmp_variable, source_ref=node.source_ref, ), right=node.subnode_source.getRight(), operator=node.subnode_source.getOperator(), source_ref=node.source_ref, ), source_ref=node.source_ref, ), StatementLocalsDictOperationSet( locals_scope=provider.getLocalsScope(), variable_name=variable_name, value=ExpressionTempVariableRef( variable=tmp_variable, source_ref=node.source_ref, ), source_ref=node.source_ref, ), ), final=StatementReleaseVariable( variable=tmp_variable, source_ref=node.source_ref ), source_ref=node.source_ref, ), ) ) node.parent.replaceStatement(node, statements) else: new_node = StatementLocalsDictOperationSet( locals_scope=provider.getLocalsScope(), variable_name=variable_name, value=node.subnode_source, source_ref=node.source_ref, ) node.parent.replaceChild(node, new_node) else: variable = provider.getVariableForAssignment( variable_name=variable_name ) new_node = StatementAssignmentVariable( variable=variable, source=node.subnode_source, source_ref=node.source_ref, ) variable.addVariableUser(provider) node.parent.replaceChild(node, new_node) del node.parent del node.provider elif node.isStatementDelVariableName(): variable_name = node.getVariableName() provider = node.provider if self._shouldUseLocalsDict(provider, variable_name): # Classes always assign to locals dictionary except for closure # variables taken. new_node = StatementLocalsDictOperationDel( locals_scope=provider.getLocalsScope(), variable_name=variable_name, tolerant=node.tolerant, source_ref=node.source_ref, ) else: variable = provider.getVariableForAssignment( variable_name=variable_name ) new_node = StatementDelVariable( variable=variable, tolerant=node.tolerant, source_ref=node.source_ref, ) variable.addVariableUser(provider) parent = node.parent node.finalize() parent.replaceChild(node, new_node)
def _buildInplaceAssignSliceNode( provider, lookup_source, lower, upper, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref, ): # Due to the 3 inputs, which we need to also put into temporary variables, # there are too many variables here, but they are needed. # pylint: disable=too-many-locals # First assign the target value, lower and upper to temporary variables. copy_to_tmp = StatementAssignmentVariable( variable=tmp_variable1, source=lookup_source, source_ref=source_ref ) final_statements = [ StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref) ] statements = [] if lower is not None: statements.append( StatementAssignmentVariable( variable=tmp_variable2, source=lower, source_ref=source_ref ) ) final_statements.append( StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref) ) lower_ref1 = ExpressionTempVariableRef( variable=tmp_variable2, source_ref=source_ref ) lower_ref2 = ExpressionTempVariableRef( variable=tmp_variable2, source_ref=source_ref ) else: assert tmp_variable2 is None lower_ref1 = lower_ref2 = None if upper is not None: statements.append( StatementAssignmentVariable( variable=tmp_variable3, source=upper, source_ref=source_ref ) ) final_statements.append( StatementReleaseVariable(variable=tmp_variable3, source_ref=source_ref) ) upper_ref1 = ExpressionTempVariableRef( variable=tmp_variable3, source_ref=source_ref ) upper_ref2 = ExpressionTempVariableRef( variable=tmp_variable3, source_ref=source_ref ) else: assert tmp_variable3 is None upper_ref1 = upper_ref2 = None use_sliceobj = python_version >= 300 # Second assign the in-place result over the original value. if use_sliceobj: statements.append( StatementAssignmentSubscript( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), subscript=ExpressionBuiltinSlice( start=lower_ref1, stop=upper_ref1, step=None, source_ref=source_ref ), source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), subscript=ExpressionBuiltinSlice( start=lower_ref2, stop=upper_ref2, step=None, source_ref=source_ref, ), source_ref=source_ref, ), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) ) else: statements.append( StatementAssignmentSlice( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), lower=lower_ref1, upper=upper_ref1, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSliceLookup( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), lower=lower_ref2, upper=upper_ref2, source_ref=source_ref, ), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) ) return ( copy_to_tmp, makeTryFinallyStatement( provider=provider, tried=statements, final=final_statements, source_ref=source_ref, ), )
def _buildInplaceAssignAttributeNode( provider, lookup_source, attribute_name, tmp_variable1, tmp_variable2, operator, expression, source_ref, ): # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable=tmp_variable1, source=ExpressionAttributeLookup( source=lookup_source.makeClone(), attribute_name=attribute_name, source_ref=source_ref, ), source_ref=source_ref, ) # Second assign the in-place result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable=tmp_variable2, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref ), right=expression, source_ref=source_ref, ), source_ref=source_ref, ) # Third, copy it back. copy_back_from_tmp = makeTryFinallyStatement( provider=provider, tried=StatementAssignmentAttribute( expression=lookup_source.makeClone(), attribute_name=attribute_name, source=ExpressionTempVariableRef( variable=tmp_variable2, source_ref=source_ref ), source_ref=source_ref, ), final=StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement( provider=provider, tried=(inplace_to_tmp, copy_back_from_tmp), final=StatementReleaseVariable( variable=tmp_variable1, source_ref=source_ref ), source_ref=source_ref, ), )