def replaceBuiltinsCallsThatRequireInterpreter( tree, future_flags ):
    def _pickLocalsForNode( node ):
        provider = node.getParentVariableProvider()

        if provider.isModule():
            return Nodes.CPythonExpressionBuiltinCallGlobals(
                source_ref = node.getSourceReference()
            )
        else:
            return Nodes.CPythonExpressionBuiltinCallLocals(
                source_ref = node.getSourceReference()
            )

    def _pickGlobalsForNode( node ):
        return Nodes.CPythonExpressionBuiltinCallGlobals(
            source_ref = node.getSourceReference()
        )

    def globals_extractor( node ):
        assert node.isEmptyCall()

        return _pickGlobalsForNode( node )

    def locals_extractor( node ):
        assert node.isEmptyCall()

        return _pickLocalsForNode( node )


    def dir_extractor( node ):
        # Only treat the empty dir() call, leave the others alone for now.
        if not node.isEmptyCall():
            return None

        return Nodes.CPythonExpressionBuiltinCallDir(
            source_ref = node.getSourceReference()
        )

    def vars_extractor( node ):
        assert node.hasOnlyPositionalArguments()

        positional_args = node.getPositionalArguments()

        if len( positional_args ) == 0:
            return Nodes.CPythonExpressionBuiltinCallLocals(
                source_ref = node.getSourceReference()
            )
        elif len( positional_args ) == 1:
            return Nodes.CPythonExpressionBuiltinCallVars(
                source     = positional_args[ 0 ],
                source_ref = node.getSourceReference()
            )
        else:
            assert False



    def eval_extractor( node ):
        assert node.hasOnlyPositionalArguments()

        positional_args = node.getPositionalArguments()

        return Nodes.CPythonExpressionBuiltinCallEval (
            source       = positional_args[0],
            globals_arg  = positional_args[1] if len( positional_args ) > 1 else None,
            locals_arg   = positional_args[2] if len( positional_args ) > 2 else None,
            mode         = "eval",
            future_flags = future_flags,
            source_ref   = node.getSourceReference()
        )

    def execfile_extractor( node ):
        assert node.parent.isStatementExpression()

        assert node.hasOnlyPositionalArguments()
        positional_args = node.getPositionalArguments()

        source_ref = node.getSourceReference()

        source_node = Nodes.CPythonExpressionFunctionCall(
            called_expression = Nodes.CPythonExpressionAttributeLookup(
                expression = Nodes.CPythonExpressionBuiltinCallOpen(
                    filename   = positional_args[0],
                    mode       = Nodes.CPythonExpressionConstant(
                        constant   = "rU",
                        source_ref = source_ref
                    ),
                    buffering  = None,
                    source_ref = source_ref
                ),
                attribute = "read",
                source_ref = source_ref
            ),
            positional_args = (),
            named_args = (),
            list_star_arg = None,
            dict_star_arg = None,
            source_ref    = source_ref
        )

        return Nodes.CPythonStatementExec(
            source       = source_node,
            globals_arg  = positional_args[1] if len( positional_args ) > 1 else None,
            locals_arg   = positional_args[2] if len( positional_args ) > 2 else None,
            future_flags = future_flags,
            source_ref   = source_ref
        )


    visitor = TreeVisitorReplaceBuiltinCalls(
        replacements = {
            "globals"  : globals_extractor,
            "locals"   : locals_extractor,
            "dir"      : dir_extractor,
            "vars"     : vars_extractor,
            "eval"     : eval_extractor,
            "execfile" : execfile_extractor
        }
    )

    TreeOperations.visitTree( tree, visitor )

    visitor = TreeVisitorFixupNewStaticmethod()

    TreeOperations.visitTree( tree, visitor )
def _prepareCodeGeneration( tree ):
    visitor = _PrepareCodeGenerationVisitor()

    TreeOperations.visitTree( tree, visitor )
def replaceConstantExecs( tree, build_node ):
    visitor = TreeVisitorOptimizeStaticExec( build_node )

    TreeOperations.visitTree( tree, visitor )