def _onStatementAssignmentVariable( self, statement ): # But now it cannot re-compute anymore: source = statement.getAssignSource() if source.willRaiseException( BaseException ): result = makeStatementExpressionOnlyReplacementNode( expression = source, node = statement ) return result, "new_raise", """\ Removed assignment that has source that will raise.""" variable_ref = statement.getTargetVariableRef() variable = variable_ref.getVariable() assert variable is not None # Assigning from and to the same variable, can be optimized away immediately, # there is no point in doing it. Exceptions are of course module variables # that collide with builtin names. if not variable.isModuleVariableReference() and \ source.isExpressionVariableRef() and \ source.getVariable() == variable: if source.mayHaveSideEffects( self ): result = makeStatementExpressionOnlyReplacementNode( expression = source, node = statement ) return result, "new_statements", """\ Reduced assignment of variable from itself to access of it.""" else: return None, "new_statements", """\ Removed assignment of variable from itself which is known to be defined.""" # If the assignment source has side effects, we can simply evaluate them # beforehand, we have already visited and evaluated them before. if source.isExpressionSideEffects(): statements = [ makeStatementExpressionOnlyReplacementNode( side_effect, statement ) for side_effect in source.getSideEffects() ] statements.append( statement ) result = makeStatementsSequenceReplacementNode( statements = statements, node = statement, ) source.replaceWith( source.getExpression() ) # Need to update it. source = statement.getAssignSource() result = result, "new_statements", """\ Side effects of assignments promoted to statements.""" else: result = statement, None, None value_friend = source.getValueFriend( self ) assert value_friend is not None old_value_friend = None if variable.isModuleVariableReference(): self.onModuleVariableAssigned( variable, value_friend ) elif variable.isLocalVariable(): self.onLocalVariableAssigned( variable, value_friend ) elif variable.isTempVariableReference(): self.onTempVariableAssigned( variable, value_friend ) if old_value_friend is not None: old_value_friend.onRelease( self ) return result
def _onStatementAssignmentVariable(self, statement): # But now it cannot re-compute anymore: source = statement.getAssignSource() if source.willRaiseException(BaseException): result = makeStatementExpressionOnlyReplacementNode( expression=source, node=statement) return result, "new_raise", """\ Removed assignment that has source that will raise.""" variable_ref = statement.getTargetVariableRef() variable = variable_ref.getVariable() assert variable is not None # Assigning from and to the same variable, can be optimized away # immediately, there is no point in doing it. Exceptions are of course # module variables that collide with builtin names. if not variable.isModuleVariableReference() and \ source.isExpressionVariableRef() and \ source.getVariable() == variable: if source.mayHaveSideEffects(): result = makeStatementExpressionOnlyReplacementNode( expression=source, node=statement) return result, "new_statements", """\ Reduced assignment of variable from itself to access of it.""" else: return None, "new_statements", """\ Removed assignment of variable from itself which is known to be defined.""" # If the assignment source has side effects, we can simply evaluate them # beforehand, we have already visited and evaluated them before. if source.isExpressionSideEffects(): statements = [ makeStatementExpressionOnlyReplacementNode( side_effect, statement) for side_effect in source.getSideEffects() ] statements.append(statement) result = makeStatementsSequenceReplacementNode( statements=statements, node=statement, ) source.replaceWith(source.getExpression()) # Need to update it. source = statement.getAssignSource() result = result, "new_statements", """\ Side effects of assignments promoted to statements.""" else: result = statement, None, None if variable.isModuleVariableReference(): self.onModuleVariableAssigned(variable, source) elif variable.isLocalVariable(): self.onLocalVariableAssigned(variable, source) elif variable.isTempVariableReference(): self.onTempVariableAssigned(variable, source) return result
def _onStatementsFrame( self, statements_sequence ): assert statements_sequence.isStatementsFrame() new_statements = [] statements = statements_sequence.getStatements() assert statements, statements_sequence for count, statement in enumerate( statements ): # May be frames embedded. if statement.isStatementsFrame(): new_statement = self.onStatementsSequence( statement ) else: new_statement = self.onStatement( statement ) if new_statement is not None: if new_statement.isStatementsSequence() and not new_statement.isStatementsFrame(): new_statements.extend( new_statement.getStatements() ) else: new_statements.append( new_statement ) if statement is not statements[-1] and new_statement.isStatementAborting(): self.signalChange( "new_statements", statements[ count + 1 ].getSourceReference(), "Removed dead statements." ) break if not new_statements: return None outside_pre = [] while new_statements and not new_statements[0].mayRaiseException( BaseException ): outside_pre.append( new_statements[0] ) del new_statements[0] outside_post = [] while new_statements and not new_statements[-1].mayRaiseException( BaseException ): outside_post.insert( 0, new_statements[-1] ) del new_statements[-1] if outside_pre or outside_post: if new_statements: statements_sequence.setStatements( tuple( new_statements ) ) return makeStatementsSequenceReplacementNode( statements = outside_pre + [ statements_sequence ] + outside_post, node = statements_sequence ) else: return makeStatementsSequenceReplacementNode( statements = outside_pre + outside_post, node = statements_sequence ) else: if statements != new_statements: statements_sequence.setStatements( tuple( new_statements ) ) return statements_sequence
def _onStatementsFrame(self, statements_sequence): assert statements_sequence.isStatementsFrame() new_statements = [] statements = statements_sequence.getStatements() assert statements, statements_sequence for count, statement in enumerate(statements): # May be frames embedded. if statement.isStatementsFrame(): new_statement = self.onStatementsSequence(statement) else: new_statement = self.onStatement(statement) if new_statement is not None: if new_statement.isStatementsSequence( ) and not new_statement.isStatementsFrame(): new_statements.extend(new_statement.getStatements()) else: new_statements.append(new_statement) if statement is not statements[ -1] and new_statement.isStatementAborting(): self.signalChange( "new_statements", statements[count + 1].getSourceReference(), "Removed dead statements.") break if not new_statements: return None outside_pre = [] while new_statements and not new_statements[0].mayRaiseException( BaseException): outside_pre.append(new_statements[0]) del new_statements[0] outside_post = [] while new_statements and not new_statements[-1].mayRaiseException( BaseException): outside_post.insert(0, new_statements[-1]) del new_statements[-1] if outside_pre or outside_post: if new_statements: statements_sequence.setStatements(tuple(new_statements)) return makeStatementsSequenceReplacementNode( statements=outside_pre + [statements_sequence] + outside_post, node=statements_sequence) else: return makeStatementsSequenceReplacementNode( statements=outside_pre + outside_post, node=statements_sequence) else: if statements != new_statements: statements_sequence.setStatements(tuple(new_statements)) return statements_sequence