def convertFunctionCallToOutline(provider, function_ref, values): # This has got to have pretty man details, pylint: disable=R0914 function_body = function_ref.getFunctionBody() # TODO: Use the call location source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody(provider=provider, name="inline", body=None, source_ref=source_ref) clone = function_body.getBody().makeClone() temp_scope = outline_body.getOutlineTempScope() translation = {} for variable in function_body.getLocalVariables(): # TODO: Later we should be able to do that too. assert not variable.isSharedTechnically() new_variable = outline_body.allocateTempVariable( temp_scope=temp_scope, name=variable.getName()) # TODO: Lets update all at once maybe, it would take less visits. updateVariableUsage(clone, old_variable=variable, new_variable=new_variable) translation[variable.getName()] = new_variable statements = [] argument_names = function_body.getParameters().getAllNames() assert len(argument_names) == len(values), (argument_names, values) for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable_ref=makeVariableTargetRefNode( variable=translation[argument_name], source_ref=source_ref), source=value, source_ref=source_ref, )) body = makeStatementsSequence(statements=(statements, clone), allow_none=False, source_ref=source_ref) outline_body.setBody(body) return outline_body
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, source_ref, function_body): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 tmp_variables = [] if assign_provider: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) # First assign the iterator if we are an outline. if assign_provider: statements = [ StatementAssignmentVariable( variable_ref = makeVariableTargetRefNode( variable = iter_tmp, source_ref = source_ref ), source = ExpressionBuiltinIter1( value = buildNode( provider = provider, node = node.generators[0].iter, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref.atInternal() ) ] else: statements = [] if start_value is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = container_tmp, source_ref = source_ref ), source = start_value, source_ref = source_ref.atInternal() ) ) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class( ExpressionTempVariableRef( variable = container_tmp, source_ref = source_ref ), buildNode( provider = function_body, node = node.elt, source_ref = source_ref ), source_ref = source_ref ) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class( buildNode( provider = function_body, node = node.elt, source_ref = source_ref ), source_ref = source_ref ) else: assert emit_class is ExpressionDictOperationSet current_body = ExpressionDictOperationSet( dict_arg = ExpressionTempVariableRef( variable = container_tmp, source_ref = source_ref ), key = buildNode( provider = function_body, node = node.key, source_ref = source_ref, ), value = buildNode( provider = function_body, node = node.value, source_ref = source_ref, ), source_ref = source_ref ) current_body = StatementExpressionOnly( expression = current_body, source_ref = source_ref ) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope = temp_scope, name = "iter_value_%d" % count ) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode( variable = iter_tmp, source_ref = source_ref ) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1( value = buildNode( provider = function_body, node = qual.iter, source_ref = source_ref ), source_ref = source_ref ) tmp_iter_variable = function_body.allocateTempVariable( temp_scope = temp_scope, name = "contraction_iter_%d" % count ) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source = value_iterator, source_ref = source_ref ) ] iterator_ref = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ) loop_statements = [ makeTryExceptSingleHandlerNode( provider = function_body, tried = makeStatementsSequenceFromStatement( statement = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source = ExpressionBuiltinNext1( value = iterator_ref, source_ref = source_ref ), source_ref = source_ref ) ), exception_name = "StopIteration", handler_body = makeStatementsSequenceFromStatement( statement = StatementBreakLoop( source_ref = source_ref.atInternal() ) ), source_ref = source_ref ), buildAssignmentStatements( provider = provider if assign_provider else function_body, temp_provider = function_body, node = qual.target, source = ExpressionTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source_ref = source_ref ) ] conditions = buildNodeList( provider = function_body, nodes = qual.ifs, source_ref = source_ref ) if len(conditions) >= 1: loop_statements.append( StatementConditional( condition = buildAndNode( values = conditions, source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = current_body ), no_branch = None, source_ref = source_ref ) ) else: loop_statements.append(current_body) nested_statements.append( StatementLoop( body = StatementsSequence( statements = mergeStatements(loop_statements), source_ref = source_ref ), source_ref = source_ref ) ) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable( variable = tmp_iter_variable, source_ref = source_ref ) ) current_body = StatementsSequence( statements = mergeStatements(nested_statements, False), source_ref = source_ref ) statements.append(current_body) statements = mergeStatements(statements) if emit_class is ExpressionYield: statements.insert( 0, StatementGeneratorEntry( source_ref = source_ref ) ) release_statements = [ StatementReleaseVariable( variable = tmp_variable, source_ref = source_ref ) for tmp_variable in tmp_variables ] return statements, release_statements
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, function_body, source_ref): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=too-many-branches,too-many-locals # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. tmp_variables = [] if assign_provider: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) # First assign the iterator if we are an outline. if assign_provider: statements = [ StatementAssignmentVariable( variable_ref=makeVariableTargetRefNode(variable=iter_tmp, source_ref=source_ref), source=ExpressionBuiltinIter1(value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref.atInternal()) ] else: statements = [] if start_value is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp, source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal())) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is StatementDictOperationSet current_body = StatementDictOperationSet( dict_arg=ExpressionTempVariableRef(variable=container_tmp, source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) if current_body.isExpression(): current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode(variable=iter_tmp, source_ref=source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] iterator_ref = ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable, source_ref=source_ref), source=ExpressionBuiltinNext1(value=iterator_ref, source_ref=source_ref), source_ref=source_ref), exception_name="StopIteration", handler_body=StatementLoopBreak( source_ref=source_ref.atInternal()), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef(variable=tmp_value_variable, source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) >= 1: loop_statements.append( StatementConditional( condition=buildAndNode(values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable(variable=tmp_iter_variable, source_ref=source_ref)) current_body = StatementsSequence(statements=mergeStatements( nested_statements, False), source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) release_statements = [ StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) for tmp_variable in tmp_variables ] return statements, release_statements
def convertFunctionCallToOutline(provider, function_ref, values): # This has got to have pretty man details, pylint: disable=R0914 function_body = function_ref.getFunctionBody() # TODO: Use the call location source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody( provider = provider, name = "inline", body = None, source_ref = source_ref ) clone = function_body.getBody().makeClone() temp_scope = outline_body.getOutlineTempScope() translation = {} for variable in function_body.getLocalVariables(): # TODO: Later we should be able to do that too. assert not variable.isSharedTechnically() new_variable = outline_body.allocateTempVariable( temp_scope = temp_scope, name = variable.getName() ) # TODO: Lets update all at once maybe, it would take less visits. updateVariableUsage( clone, old_variable = variable, new_variable = new_variable ) translation[variable.getName()] = new_variable statements = [] argument_names = function_body.getParameters().getAllNames() assert len(argument_names) == len(values), (argument_names, values) for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable_ref = makeVariableTargetRefNode( variable = translation[argument_name], source_ref = source_ref ), source = value, source_ref = source_ref, ) ) body = makeStatementsSequence( statements = (statements, clone), allow_none = False, source_ref = source_ref ) outline_body.setBody(body) return outline_body