Esempio n. 1
0
    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        ChildrenHavingMixin.__init__(
            self,
            values = {},
        )

        PythonModuleMixin.__init__(
            self,
            name         = name,
            package_name = package_name
        )

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()
        self.cross_used_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None
Esempio n. 2
0
    def __init__(self, name, code_prefix, source_ref):
        CodeNodeBase.__init__(self,
                              name=name,
                              code_prefix=code_prefix,
                              source_ref=source_ref)

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()
Esempio n. 3
0
class ClosureGiverNodeBase( CodeNodeBase ):
    """ Mixin for nodes that provide variables for closure takers. """
    def __init__( self, name, code_prefix, source_ref ):
        CodeNodeBase.__init__(
            self,
            name        = name,
            code_prefix = code_prefix,
            source_ref  = source_ref
        )

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()

    def hasProvidedVariable( self, variable_name ):
        return variable_name in self.providing

    def getProvidedVariable( self, variable_name ):
        if variable_name not in self.providing:
            self.providing[ variable_name ] = self.createProvidedVariable(
                variable_name = variable_name
            )

        return self.providing[ variable_name ]

    def createProvidedVariable( self, variable_name ):
        # Virtual method, pylint: disable=R0201,W0613
        assert type( variable_name ) is str

        return None

    def registerProvidedVariables( self, variables ):
        for variable in variables:
            self.registerProvidedVariable( variable )

    def registerProvidedVariable( self, variable ):
        assert variable is not None

        self.providing[ variable.getName() ] = variable

    def getProvidedVariables( self ):
        return self.providing.values()

    def getTempKeeperVariable( self ):
        name = "keeper_%d" % len( self.keeper_variables )

        from nuitka import Variables

        result = Variables.TempKeeperVariable(
            owner         = self,
            variable_name = name
        )

        self.keeper_variables.add( result )

        return result
Esempio n. 4
0
def startTraversal():
    # Using global here, as this is really a singleton, in the form of a module,
    # pylint: disable=W0603
    global active_modules, done_modules

    active_modules = OrderedSet(root_modules)
    done_modules = OrderedSet()

    for active_module in active_modules:
        active_module.startTraversal()
Esempio n. 5
0
class ClosureGiverNodeBase(CodeNodeBase):
    """ Mixin for nodes that provide variables for closure takers. """
    def __init__(self, name, code_prefix, source_ref):
        CodeNodeBase.__init__(self,
                              name=name,
                              code_prefix=code_prefix,
                              source_ref=source_ref)

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()

    def hasProvidedVariable(self, variable_name):
        return variable_name in self.providing

    def getProvidedVariable(self, variable_name):
        if variable_name not in self.providing:
            self.providing[variable_name] = self.createProvidedVariable(
                variable_name=variable_name)

        return self.providing[variable_name]

    def createProvidedVariable(self, variable_name):
        # Virtual method, pylint: disable=R0201,W0613
        assert type(variable_name) is str

        return None

    def registerProvidedVariables(self, variables):
        for variable in variables:
            self.registerProvidedVariable(variable)

    def registerProvidedVariable(self, variable):
        assert variable is not None

        self.providing[variable.getName()] = variable

    def getProvidedVariables(self):
        return self.providing.values()

    def getTempKeeperVariable(self):
        name = "keeper_%d" % len(self.keeper_variables)

        from nuitka import Variables

        result = Variables.TempKeeperVariable(owner=self, variable_name=name)

        self.keeper_variables.add(result)

        return result
Esempio n. 6
0
    def __init__( self, name, package, source_ref ):
        assert type(name) is str, type(name)
        assert "." not in name, name
        assert package is None or ( type( package ) is str and package != "" )

        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        ChildrenHavingMixin.__init__(
            self,
            values = {}
        )

        MarkContainsTryExceptIndicator.__init__( self )

        self.package = package

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()
Esempio n. 7
0
    def __init__( self, parent ):
        ConstraintCollectionBase.__init__(
            self,
            parent = parent
        )

        self.branch_only_traces = OrderedSet()
Esempio n. 8
0
class ConstraintCollectionBranch( ConstraintCollectionBase ):
    def __init__( self, parent ):
        ConstraintCollectionBase.__init__(
            self,
            parent = parent
        )

        self.branch_only_traces = OrderedSet()

    def process( self, branch ):
        assert branch.isStatementsSequence(), branch

        result = self.onStatementsSequence( branch )

        if result is not branch:
            branch.replaceWith( result )

    def onVariableSet( self, target_node, value_friend ):
        # Add a new trace, allocating a new version for the variable, and remember the value
        # friend.
        key = self.parent.onVariableSet(
            target_node  = target_node,
            value_friend = value_friend
        )

        # Remember the version, because it was added to this branch only, which matters
        # for merge later.
        self.branch_only_traces.add( key )

        return key

    def onVariableUsage( self, ref_node ):
        key = self.parent.onVariableUsage(
            ref_node = ref_node
        )

        if key is not None:
            self.branch_only_traces.add( key )

        return key

    def getBranchOnlyTraces( self ):
        return self.branch_only_traces

    def mergeBranches( self, collection_yes, collection_no ):
        # Branches in branches, should ask parent about merging them.
        return self.parent.mergeBranches( collection_yes, collection_no )
Esempio n. 9
0
    def __init__( self, name, code_prefix, source_ref ):
        CodeNodeBase.__init__(
            self,
            name        = name,
            code_prefix = code_prefix,
            source_ref  = source_ref
        )

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()
Esempio n. 10
0
    def __init__(self, name, package, source_ref):
        assert type(name) is str, type(name)
        assert "." not in name, name
        assert package is None or (type(package) is str and package != "")

        ClosureGiverNodeBase.__init__(self,
                                      name=name,
                                      code_prefix="module",
                                      source_ref=source_ref)

        ChildrenHavingMixin.__init__(self, values={})

        MarkContainsTryExceptIndicator.__init__(self)

        self.package = package

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()
Esempio n. 11
0
class ConstraintCollectionBranch(ConstraintCollectionBase):
    def __init__(self, parent):
        ConstraintCollectionBase.__init__(self, parent=parent)

        self.branch_only_traces = OrderedSet()

    def process(self, branch):
        assert branch.isStatementsSequence(), branch

        result = self.onStatementsSequence(branch)

        if result is not branch:
            branch.replaceWith(result)

    def onVariableSet(self, target_node, value_friend):
        # Add a new trace, allocating a new version for the variable, and remember the value
        # friend.
        key = self.parent.onVariableSet(target_node=target_node,
                                        value_friend=value_friend)

        # Remember the version, because it was added to this branch only, which matters
        # for merge later.
        self.branch_only_traces.add(key)

        return key

    def onVariableUsage(self, ref_node):
        key = self.parent.onVariableUsage(ref_node=ref_node)

        if key is not None:
            self.branch_only_traces.add(key)

        return key

    def getBranchOnlyTraces(self):
        return self.branch_only_traces

    def mergeBranches(self, collection_yes, collection_no):
        # Branches in branches, should ask parent about merging them.
        return self.parent.mergeBranches(collection_yes, collection_no)
Esempio n. 12
0
    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        PythonModuleMixin.__init__(
            self,
            name         = name,
            package_name = package_name
        )


        ChildrenHavingMixin.__init__(
            self,
            values = {
                "body" : None # delayed
            },
        )

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()
        self.cross_used_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None
Esempio n. 13
0
    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(self,
                                      name=name,
                                      code_prefix="module",
                                      source_ref=source_ref)

        ChildrenHavingMixin.__init__(
            self,
            values={},
        )

        MarkContainsTryExceptIndicator.__init__(self)

        PythonModuleMixin.__init__(self, name=name, package_name=package_name)

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None
Esempio n. 14
0
class PythonModule(PythonModuleMixin, ChildrenHavingMixin,
                   ClosureGiverNodeBase):
    """ Module

        The module is the only possible root of a tree. When there are many
        modules they form a forrest.
    """

    kind = "PYTHON_MODULE"

    named_children = (
        "body",
    )

    checkers = {
        "body": checkModuleBody
    }

    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        PythonModuleMixin.__init__(
            self,
            name         = name,
            package_name = package_name
        )


        ChildrenHavingMixin.__init__(
            self,
            values = {
                "body" : None # delayed
            },
        )

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()
        self.cross_used_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None

    def getDetails(self):
        return {
            "filename" : self.source_ref.getFilename(),
            "package"  : self.package_name,
            "name"     : self.name
        }

    def asXml(self):
        result = super(PythonModule, self).asXml()

        for function_body in self.functions:
            result.append(function_body.asXml())

        return result

    getBody = ChildrenHavingMixin.childGetter("body")
    setBody = ChildrenHavingMixin.childSetter("body")

    @staticmethod
    def isPythonModule():
        return True

    def getParent(self):
        assert False

    def getParentVariableProvider(self):
        return None

    def getVariables(self):
        return self.variables

    def getFilename(self):
        return self.source_ref.getFilename()

    def getVariableForAssignment(self, variable_name):
        return self.getProvidedVariable(variable_name)

    def getVariableForReference(self, variable_name):
        return self.getProvidedVariable(variable_name)

    def getVariableForClosure(self, variable_name):
        return self.getProvidedVariable(
            variable_name = variable_name
        )

    def createProvidedVariable(self, variable_name):
        result = Variables.ModuleVariable(
            module        = self,
            variable_name = variable_name
        )

        assert result not in self.variables
        self.variables.add(result)

        return result

    def isEarlyClosure(self):
        # Modules should immediately closure variables on use.
        # pylint: disable=R0201
        return True

    def getCodeName(self):
        def r(match):
            c = match.group()
            if c == '.':
                return "$"
            else:
                return "$$%d$" % ord(c)

        return "".join(
            re.sub("[^a-zA-Z0-9_]", r ,c)
            for c in
            self.getFullName()
        )

    def addFunction(self, function_body):
        assert function_body not in self.functions

        self.functions.add(function_body)

    def getFunctions(self):
        return self.functions

    def startTraversal(self):
        self.active_functions = OrderedSet()

    def addUsedFunction(self, function_body):
        assert function_body in self.functions

        assert function_body.isExpressionFunctionBody()

        if function_body not in self.active_functions:
            self.active_functions.add(function_body)

    def getUsedFunctions(self):
        return self.active_functions

    def addCrossUsedFunction(self, function_body):
        if function_body not in self.cross_used_functions:
            self.cross_used_functions.add(function_body)

    def getCrossUsedFunctions(self):
        return self.cross_used_functions

    def getOutputFilename(self):
        main_filename = self.getFilename()

        if main_filename.endswith(".py"):
            result = main_filename[:-3]
        else:
            result = main_filename

        # There are some characters that somehow are passed to shell, by
        # Scons or unknown, so lets avoid them for now.
        return result.replace(")","").replace("(","")

    # TODO: Can't really use locals for modules, this should probably be made
    # sure to not be used.
    @staticmethod
    def getLocalsMode():
        return "copy"

    def computeModule(self):
        self.collection = ConstraintCollectionModule()

        module_body = self.getBody()

        if module_body is not None:
            result = module_body.computeStatementsSequence(
                constraint_collection = self.collection
            )

            if result is not module_body:
                self.setBody(result)

        self.collection.makeVariableTraceOptimizations(self)
Esempio n. 15
0
#     See the License for the specific language governing permissions and
#     limitations under the License.
#
""" This to keep track of used modules.

    There is a set of root modules, which are user specified, and must be
    processed. As they go, they add more modules to active modules list
    and move done modules out of it.

    That process can be restarted and modules will be fetched back from
    the existing set of modules.
"""

from nuitka.oset import OrderedSet

root_modules = OrderedSet()


def addRootModule(module):
    root_modules.add(module)


def getRootModules():
    return root_modules


active_modules = OrderedSet()
done_modules = OrderedSet()


def startTraversal():
Esempio n. 16
0
 def startTraversal(self):
     self.active_functions = OrderedSet()
Esempio n. 17
0
class ClosureGiverNodeBase(CodeNodeBase):
    """ Mixin for nodes that provide variables for closure takers. """
    def __init__(self, name, code_prefix, source_ref):
        CodeNodeBase.__init__(self,
                              name=name,
                              code_prefix=code_prefix,
                              source_ref=source_ref)

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()

        self.temp_variables = OrderedDict()

        self.temp_scopes = OrderedDict()

    def hasProvidedVariable(self, variable_name):
        return variable_name in self.providing

    def getProvidedVariable(self, variable_name):
        if variable_name not in self.providing:
            self.providing[variable_name] = self.createProvidedVariable(
                variable_name=variable_name)

        return self.providing[variable_name]

    def createProvidedVariable(self, variable_name):
        # Virtual method, pylint: disable=R0201,W0613
        assert type(variable_name) is str

        return None

    def registerProvidedVariables(self, variables):
        for variable in variables:
            self.registerProvidedVariable(variable)

    def registerProvidedVariable(self, variable):
        assert variable is not None

        self.providing[variable.getName()] = variable

    def getProvidedVariables(self):
        return self.providing.values()

    def allocateTempKeeperVariable(self):
        name = "keeper_%d" % len(self.keeper_variables)

        result = Variables.TempKeeperVariable(owner=self, variable_name=name)

        self.keeper_variables.add(result)

        return result

    def getTempKeeperVariables(self):
        return self.keeper_variables

    def removeTempKeeperVariable(self, variable):
        self.keeper_variables.discard(variable)

    def allocateTempScope(self, name, allow_closure=False):
        self.temp_scopes[name] = self.temp_scopes.get(name, 0) + 1

        # TODO: Instead of using overly long code name, could just visit parents
        # and make sure to allocate the scope at the top.
        if allow_closure:
            return "%s_%s_%d" % (self.getCodeName(), name,
                                 self.temp_scopes[name])
        else:
            return "%s_%d" % (name, self.temp_scopes[name])

    def allocateTempVariable(self, temp_scope, name):
        if temp_scope is not None:
            full_name = "%s__%s" % (temp_scope, name)
        else:
            full_name = name

        del name

        assert full_name not in self.temp_variables, full_name

        result = Variables.TempVariable(owner=self, variable_name=full_name)

        self.temp_variables[full_name] = result

        return result

    def getTempVariable(self, temp_scope, name):
        if temp_scope is not None:
            full_name = "%s__%s" % (temp_scope, name)
        else:
            full_name = name

        return self.temp_variables[full_name]

    def getTempVariables(self):
        return tuple(self.temp_variables.values())

    def removeTempVariable(self, variable):
        del self.temp_variables[variable.getName()]
Esempio n. 18
0
class PythonModule(PythonModuleMixin, ChildrenHavingMixin,
                   ClosureGiverNodeBase):
    """ Module

        The module is the only possible root of a tree. When there are many
        modules they form a forrest.
    """

    kind = "PYTHON_MODULE"

    named_children = (
        "body",
    )

    checkers = {
        "body": checkModuleBody
    }

    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        ChildrenHavingMixin.__init__(
            self,
            values = {},
        )

        PythonModuleMixin.__init__(
            self,
            name         = name,
            package_name = package_name
        )

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()
        self.cross_used_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None

    def getDetails(self):
        return {
            "filename" : self.source_ref.getFilename(),
            "package"  : self.package_name,
            "name"     : self.name
        }

    def asXml(self):
        # The class is new style, false alarm: pylint: disable=E1002
        result = super( PythonModule, self ).asXml()

        for function_body in self.functions:
            result.append( function_body.asXml() )

        return result

    getBody = ChildrenHavingMixin.childGetter("body")
    setBody = ChildrenHavingMixin.childSetter("body")

    def isPythonModule(self):
        return True

    def getParent(self):
        assert False

    def getParentVariableProvider(self):
        return None

    def getVariables(self):
        return self.variables

    def getFilename(self):
        return self.source_ref.getFilename()

    def getVariableForAssignment(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForReference(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForClosure(self, variable_name):
        return self.getProvidedVariable(
            variable_name = variable_name
        )

    def createProvidedVariable(self, variable_name):
        result = Variables.ModuleVariable(
            module        = self,
            variable_name = variable_name
        )

        assert result not in self.variables
        self.variables.add(result)

        return result

    def isEarlyClosure(self):
        # Modules should immediately closure variables on use.
        # pylint: disable=R0201
        return True

    def getCodeName(self):
        def r(match):
            c = match.group()
            if c == '.':
                return "$"
            else:
                return "$$%d$" % ord(c)

        return "module_" + \
          "".join(re.sub("[^a-zA-Z0-9_]", r ,c) for c in self.getFullName())

    def addFunction(self, function_body):
        assert function_body not in self.functions

        self.functions.add( function_body )

    def getFunctions(self):
        return self.functions

    def startTraversal(self):
        self.active_functions = OrderedSet()

    def addUsedFunction(self, function_body):
        assert function_body in self.functions

        assert function_body.isExpressionFunctionBody()

        if function_body not in self.active_functions:
            self.active_functions.add(function_body)

    def getUsedFunctions(self):
        return self.active_functions

    def addCrossUsedFunction(self, function_body):
        if function_body not in self.cross_used_functions:
            self.cross_used_functions.add(function_body)

    def getCrossUsedFunctions(self):
        return self.cross_used_functions

    def getOutputFilename(self):
        main_filename = self.getFilename()

        if main_filename.endswith(".py"):
            result = main_filename[:-3]
        else:
            result = main_filename

        # There are some characters that somehow are passed to shell, by
        # Scons or unknown, so lets avoid them for now.
        return result.replace(")","").replace("(","")

    # TODO: Can't really use locals for modules, this should probably be made
    # sure to not be used.
    def getLocalsMode(self):
        return "copy"
Esempio n. 19
0
class PythonModule(PythonModuleMixin, ChildrenHavingMixin,
                   ClosureGiverNodeBase, MarkContainsTryExceptIndicator):
    """ Module

        The module is the only possible root of a tree. When there are many
        modules they form a forrest.
    """

    kind = "PYTHON_MODULE"

    named_children = ("body", )

    checkers = {"body": checkModuleBody}

    def __init__(self, name, package_name, source_ref):
        ClosureGiverNodeBase.__init__(self,
                                      name=name,
                                      code_prefix="module",
                                      source_ref=source_ref)

        ChildrenHavingMixin.__init__(
            self,
            values={},
        )

        MarkContainsTryExceptIndicator.__init__(self)

        PythonModuleMixin.__init__(self, name=name, package_name=package_name)

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

        self.active_functions = OrderedSet()

        # SSA trace based information about the module.
        self.collection = None

    def getDetails(self):
        return {
            "filename": self.source_ref.getFilename(),
            "package": self.package_name,
            "name": self.name
        }

    def asXml(self):
        # The class is new style, false alarm: pylint: disable=E1002
        result = super(PythonModule, self).asXml()

        for function_body in self.functions:
            result.append(function_body.asXml())

        return result

    getBody = ChildrenHavingMixin.childGetter("body")
    setBody = ChildrenHavingMixin.childSetter("body")

    def isPythonModule(self):
        return True

    def getParent(self):
        assert False

    def getParentVariableProvider(self):
        return None

    def getVariables(self):
        return self.variables

    def getFilename(self):
        return self.source_ref.getFilename()

    def getVariableForAssignment(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForReference(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForClosure(self, variable_name):
        return self.getProvidedVariable(variable_name=variable_name)

    def createProvidedVariable(self, variable_name):
        result = Variables.ModuleVariable(module=self,
                                          variable_name=variable_name)

        assert result not in self.variables
        self.variables.add(result)

        return result

    def isEarlyClosure(self):
        # Modules should immediately closure variables on use.
        # pylint: disable=R0201
        return True

    def getCodeName(self):
        def r(match):
            c = match.group()
            if c == '.':
                return "$"
            else:
                return "$$%d$" % ord(c)

        return "module_" + \
          "".join(re.sub("[^a-zA-Z0-9_]", r ,c) for c in self.getFullName())

    def addFunction(self, function_body):
        assert function_body not in self.functions

        self.functions.add(function_body)

    def getFunctions(self):
        return self.functions

    def startTraversal(self):
        self.active_functions = OrderedSet()

    def addUsedFunction(self, function_body):
        assert function_body in self.functions

        assert function_body.isExpressionFunctionBody()

        if function_body not in self.active_functions:
            self.active_functions.add(function_body)

    def getUsedFunctions(self):
        return self.active_functions

    def getOutputFilename(self):
        main_filename = self.getFilename()

        if main_filename.endswith(".py"):
            return main_filename[:-3]
        else:
            return main_filename
Esempio n. 20
0
class PythonModule( ChildrenHavingMixin, ClosureGiverNodeBase,
                    MarkContainsTryExceptIndicator ):
    """ Module

        The module is the only possible root of a tree. When there are many modules
        they form a forrest.
    """

    kind = "PYTHON_MODULE"

    named_children = ( "body", )

    def __init__( self, name, package, source_ref ):
        assert type(name) is str, type(name)
        assert "." not in name, name
        assert package is None or ( type( package ) is str and package != "" )

        ClosureGiverNodeBase.__init__(
            self,
            name        = name,
            code_prefix = "module",
            source_ref  = source_ref
        )

        ChildrenHavingMixin.__init__(
            self,
            values = {}
        )

        MarkContainsTryExceptIndicator.__init__( self )

        self.package = package

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

    def getDetails( self ):
        return {
            "filename" : self.source_ref.getFilename(),
            "package"  : self.package,
            "name"     : self.name
        }

    def asXml( self ):
        # The class is new style, false alarm: pylint: disable=E1002
        result = super( PythonModule, self ).asXml()

        for function_body in self.functions:
            result.append( function_body.asXml() )

        return result

    getBody = ChildrenHavingMixin.childGetter( "body" )
    setBody = ChildrenHavingMixin.childSetter( "body" )

    def isPythonModule( self ):
        return True

    def getParent( self ):
        assert False

    def getParentVariableProvider( self ):
        return None

    def getVariables( self ):
        return self.variables

    def getFilename( self ):
        return self.source_ref.getFilename()

    def getPackage( self ):
        return self.package

    def getFullName( self ):
        if self.package:
            return self.package + "." + self.getName()
        else:
            return self.getName()

    def getVariableForAssignment( self, variable_name ):
        result = self.getProvidedVariable( variable_name )

        return result.makeReference( self )

    def getVariableForReference( self, variable_name ):
        result = self.getProvidedVariable( variable_name )

        return result.makeReference( self )

    def getVariableForClosure( self, variable_name ):
        return self.getProvidedVariable(
            variable_name = variable_name
        )

    def createProvidedVariable( self, variable_name ):
        result = Variables.ModuleVariable(
            module        = self,
            variable_name = variable_name
        )

        assert result not in self.variables
        self.variables.add( result )

        return result

    def isEarlyClosure( self ):
        # Modules should immediately closure variables on use, pylint: disable=R0201
        return True

    def isMainModule( self ):
        return False

    def getCodeName( self ):
        return "module_" + self.getFullName().replace( ".", "__" ).replace( "-", "_" )

    def addFunction( self, function_body ):
        assert function_body not in self.functions

        self.functions.add( function_body )

    def getFunctions( self ):
        return self.functions

    def getOutputFilename( self ):
        main_filename = self.getFilename()

        if main_filename.endswith( ".py" ):
            return main_filename[:-3]
        else:
            return main_filename
Esempio n. 21
0
class ClosureGiverNodeBase(CodeNodeBase):
    """ Mixin for nodes that provide variables for closure takers. """
    def __init__(self, name, code_prefix, source_ref):
        CodeNodeBase.__init__(
            self,
            name        = name,
            code_prefix = code_prefix,
            source_ref  = source_ref
        )

        self.providing = OrderedDict()

        self.keeper_variables = OrderedSet()

        self.temp_variables = OrderedDict()

        self.temp_scopes = OrderedDict()

    def hasProvidedVariable(self, variable_name):
        return variable_name in self.providing

    def getProvidedVariable(self, variable_name):
        if variable_name not in self.providing:
            self.providing[ variable_name ] = self.createProvidedVariable(
                variable_name = variable_name
            )

        return self.providing[ variable_name ]

    def createProvidedVariable(self, variable_name):
        # Virtual method, pylint: disable=R0201,W0613
        assert type( variable_name ) is str

        return None

    def registerProvidedVariables(self, variables):
        for variable in variables:
            self.registerProvidedVariable( variable )

    def registerProvidedVariable(self, variable):
        assert variable is not None

        self.providing[ variable.getName() ] = variable

    def getProvidedVariables(self):
        return self.providing.values()

    def allocateTempKeeperVariable(self):
        name = "keeper_%d" % len( self.keeper_variables )

        result = Variables.TempKeeperVariable(
            owner         = self,
            variable_name = name
        )

        self.keeper_variables.add( result )

        return result

    def getTempKeeperVariables(self):
        return self.keeper_variables

    def removeTempKeeperVariable(self, variable):
        self.keeper_variables.discard( variable )

    def allocateTempScope(self, name, allow_closure = False):
        self.temp_scopes[ name ] = self.temp_scopes.get( name, 0 ) + 1

        # TODO: Instead of using overly long code name, could just visit parents
        # and make sure to allocate the scope at the top.
        if allow_closure:
            return "%s_%s_%d" % (
                self.getCodeName(),
                name,
                self.temp_scopes[ name ]
            )
        else:
            return "%s_%d" % ( name, self.temp_scopes[ name ] )

    def allocateTempVariable(self, temp_scope, name):
        if temp_scope is not None:
            full_name = "%s__%s" % ( temp_scope, name )
        else:
            full_name = name

        del name

        assert full_name not in self.temp_variables, full_name

        result = Variables.TempVariable(
            owner         = self,
            variable_name = full_name
        )

        self.temp_variables[ full_name ] = result

        return result

    def getTempVariable(self, temp_scope, name):
        if temp_scope is not None:
            full_name = "%s__%s" % ( temp_scope, name )
        else:
            full_name = name

        return self.temp_variables[ full_name ]

    def getTempVariables(self):
        return tuple( self.temp_variables.values() )

    def removeTempVariable(self, variable):
        del self.temp_variables[ variable.getName() ]
Esempio n. 22
0
 def startTraversal(self):
     self.active_functions = OrderedSet()
Esempio n. 23
0
    def __init__(self, parent):
        ConstraintCollectionBase.__init__(self, parent=parent)

        self.branch_only_traces = OrderedSet()
Esempio n. 24
0
class PythonModule(ChildrenHavingMixin, ClosureGiverNodeBase,
                   MarkContainsTryExceptIndicator):
    """ Module

        The module is the only possible root of a tree. When there are many modules
        they form a forrest.
    """

    kind = "PYTHON_MODULE"

    named_children = ("body", )

    def __init__(self, name, package, source_ref):
        assert type(name) is str, type(name)
        assert "." not in name, name
        assert package is None or (type(package) is str and package != "")

        ClosureGiverNodeBase.__init__(self,
                                      name=name,
                                      code_prefix="module",
                                      source_ref=source_ref)

        ChildrenHavingMixin.__init__(self, values={})

        MarkContainsTryExceptIndicator.__init__(self)

        self.package = package

        self.variables = set()

        # The list functions contained in that module.
        self.functions = OrderedSet()

    def getDetails(self):
        return {
            "filename": self.source_ref.getFilename(),
            "package": self.package,
            "name": self.name
        }

    def asXml(self):
        # The class is new style, false alarm: pylint: disable=E1002
        result = super(PythonModule, self).asXml()

        for function_body in self.functions:
            result.append(function_body.asXml())

        return result

    getBody = ChildrenHavingMixin.childGetter("body")
    setBody = ChildrenHavingMixin.childSetter("body")

    def isPythonModule(self):
        return True

    def getParent(self):
        assert False

    def getParentVariableProvider(self):
        return None

    def getVariables(self):
        return self.variables

    def getFilename(self):
        return self.source_ref.getFilename()

    def getPackage(self):
        return self.package

    def getFullName(self):
        if self.package:
            return self.package + "." + self.getName()
        else:
            return self.getName()

    def getVariableForAssignment(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForReference(self, variable_name):
        result = self.getProvidedVariable(variable_name)

        return result.makeReference(self)

    def getVariableForClosure(self, variable_name):
        return self.getProvidedVariable(variable_name=variable_name)

    def createProvidedVariable(self, variable_name):
        result = Variables.ModuleVariable(module=self,
                                          variable_name=variable_name)

        assert result not in self.variables
        self.variables.add(result)

        return result

    def isEarlyClosure(self):
        # Modules should immediately closure variables on use, pylint: disable=R0201
        return True

    def isMainModule(self):
        return False

    def getCodeName(self):
        return "module_" + self.getFullName().replace(".", "__").replace(
            "-", "_")

    def addFunction(self, function_body):
        assert function_body not in self.functions

        self.functions.add(function_body)

    def getFunctions(self):
        return self.functions

    def getOutputFilename(self):
        main_filename = self.getFilename()

        if main_filename.endswith(".py"):
            return main_filename[:-3]
        else:
            return main_filename