예제 #1
0
    def onEnterNode(self, node):
        if node.isExpressionVariableNameRef():
            provider = node.provider

            try:
                variable = self._attachVariable(node, provider)
            except MaybeLocalVariableUsage:
                variable_name = node.getVariableName()

                new_node = ExpressionLocalsVariableRefOrFallback(
                    locals_scope=provider.getLocalsScope(),
                    variable_name=variable_name,
                    fallback=makeExpressionVariableRef(
                        variable=node.getParentModule().getVariableForReference(
                            variable_name
                        ),
                        locals_scope=provider.getLocalsScope(),
                        source_ref=node.source_ref,
                    ),
                    source_ref=node.source_ref,
                )
            else:
                new_node = makeExpressionVariableRef(
                    variable=variable,
                    locals_scope=provider.getLocalsScope(),
                    source_ref=node.source_ref,
                )

                variable.addVariableUser(provider)

            parent = node.parent
            node.finalize()

            parent.replaceChild(node, new_node)
예제 #2
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches, but we aim to get rid of it.
        # pylint: disable=too-many-branches

        if node.isExpressionVariableNameRef():
            provider = node.provider

            if provider.isExpressionClassBody():
                if node.needsFallback():
                    variable = provider.getVariableForReference(
                        variable_name=node.getVariableName()
                    )

                    new_node = ExpressionLocalsVariableRefOrFallback(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=node.getVariableName(),
                        fallback=makeExpressionVariableRef(
                            variable=variable,
                            locals_scope=provider.getLocalsScope(),
                            source_ref=node.source_ref,
                        ),
                        source_ref=node.source_ref,
                    )

                    variable.addVariableUser(provider)
                else:
                    new_node = ExpressionLocalsVariableRef(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=node.getVariableName(),
                        source_ref=node.source_ref,
                    )

                parent = node.parent
                node.finalize()

                parent.replaceChild(node, new_node)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider():
                node.getParentVariableProvider().addClosureVariable(node.getVariable())
        elif node.isExpressionGeneratorObjectBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Only Python3.4 or later allows for generators to have qualname.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionCoroutineObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionAsyncgenObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionClassBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python 3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementLoopBreak() or node.isStatementLoopContinue():
            current = node

            while True:
                current = current.getParent()

                if current.isStatementLoop():
                    break

                if current.isParentVariableProvider():
                    if node.isStatementLoopContinue():
                        message = "'continue' not properly in loop"
                    else:
                        message = "'break' outside loop"

                    raiseSyntaxError(message, node.getSourceReference())
예제 #3
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=too-many-branches,too-many-statements

        if node.isExpressionVariableNameRef():
            provider = node.provider

            if provider.isExpressionClassBody():
                if node.needsFallback():
                    variable = provider.getVariableForReference(
                        variable_name=node.getVariableName())

                    new_node = ExpressionLocalsVariableRefOrFallback(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=node.getVariableName(),
                        fallback=makeExpressionVariableRef(
                            variable=variable,
                            locals_scope=provider.getLocalsScope(),
                            source_ref=node.source_ref,
                        ),
                        source_ref=node.source_ref,
                    )

                    variable.addVariableUser(provider)
                else:
                    new_node = ExpressionLocalsVariableRef(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=node.getVariableName(),
                        source_ref=node.source_ref,
                    )

                parent = node.parent
                node.finalize()

                parent.replaceChild(node, new_node)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.getParentVariableProvider().addClosureVariable(
                    node.getVariable())
        elif node.isExpressionGeneratorObjectBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Only Python3.4 or later allows for generators to have qualname.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionCoroutineObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionAsyncgenObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionClassBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python 3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif (node.isExpressionAttributeLookup()
              or node.isStatementAssignmentAttribute()
              or node.isStatementDelAttribute()):
            attribute_name = node.getAttributeName()

            if attribute_name.startswith(
                    "__") and not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isCompiledPythonModule():
                        break

                    if current.isExpressionClassBody():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip("_"),
                                           attribute_name))

                        break

                    seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementLoopBreak() or node.isStatementLoopContinue():
            current = node

            while True:
                current = current.getParent()

                if current.isStatementLoop():
                    break

                if current.isParentVariableProvider():
                    if node.isStatementLoopContinue():
                        message = "'continue' not properly in loop"
                    else:
                        message = "'break' outside loop"

                    raiseSyntaxError(message, node.getSourceReference())