# Path: Cython/Compiler/Visitor.py
# class VisitorTransform(TreeVisitor):
#     """
#     A tree transform is a base class for visitors that wants to do stream
#     processing of the structure (rather than attributes etc.) of a tree.
# 
#     It implements __call__ to simply visit the argument node.
# 
#     It requires the visitor methods to return the nodes which should take
#     the place of the visited node in the result tree (which can be the same
#     or one or more replacement). Specifically, if the return value from
#     a visitor method is:
# 
#     - [] or None; the visited node will be removed (set to None if an attribute and
#     removed if in a list)
#     - A single node; the visited node will be replaced by the returned node.
#     - A list of nodes; the visited nodes will be replaced by all the nodes in the
#     list. This will only work if the node was already a member of a list; if it
#     was not, an exception will be raised. (Typically you want to ensure that you
#     are within a StatListNode or similar before doing this.)
#     """
#     def visitchildren(self, parent, attrs=None):
#         result = self._visitchildren(parent, attrs)
#         for attr, newnode in result.iteritems():
#             if not type(newnode) is list:
#                 setattr(parent, attr, newnode)
#             else:
#                 # Flatten the list one level and remove any None
#                 newlist = []
#                 for x in newnode:
#                     if x is not None:
#                         if type(x) is list:
#                             newlist += x
#                         else:
#                             newlist.append(x)
#                 setattr(parent, attr, newlist)
#         return result
# 
#     def recurse_to_children(self, node):
#         self.visitchildren(node)
#         return node
# 
#     def __call__(self, root):
#         return self._visit(root)
# 
# Path: Cython/Compiler/Nodes.py
# class CSimpleBaseTypeNode(CBaseTypeNode):
#     # name             string
#     # module_path      [string]     Qualifying name components
#     # is_basic_c_type  boolean
#     # signed           boolean
#     # longness         integer
#     # complex          boolean
#     # is_self_arg      boolean      Is self argument of C method
#     # ##is_type_arg      boolean      Is type argument of class method
# 
#     child_attrs = []
#     arg_name = None   # in case the argument name was interpreted as a type
#     module_path = []
#     is_basic_c_type = False
#     complex = False
# 
#     def analyse(self, env, could_be_name = False):
#         # Return type descriptor.
#         #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
#         type = None
#         if self.is_basic_c_type:
#             type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
#             if not type:
#                 error(self.pos, "Unrecognised type modifier combination")
#         elif self.name == "object" and not self.module_path:
#             type = py_object_type
#         elif self.name is None:
#             if self.is_self_arg and env.is_c_class_scope:
#                 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
#                 type = env.parent_type
#             ## elif self.is_type_arg and env.is_c_class_scope:
#             ##     type = Builtin.type_type
#             else:
#                 type = py_object_type
#         else:
#             if self.module_path:
#                 scope = env.find_imported_module(self.module_path, self.pos)
#                 if scope:
#                     scope.fused_to_specific = env.fused_to_specific
#             else:
#                 scope = env
# 
#             if scope:
#                 if scope.is_c_class_scope:
#                     scope = scope.global_scope()
# 
#                 type = scope.lookup_type(self.name)
#                 if type is not None:
#                     pass
#                 elif could_be_name:
#                     if self.is_self_arg and env.is_c_class_scope:
#                         type = env.parent_type
#                     ## elif self.is_type_arg and env.is_c_class_scope:
#                     ##     type = Builtin.type_type
#                     else:
#                         type = py_object_type
#                     self.arg_name = self.name
#                 else:
#                     if self.templates:
#                         if not self.name in self.templates:
#                             error(self.pos, "'%s' is not a type identifier" % self.name)
#                         type = PyrexTypes.TemplatePlaceholderType(self.name)
#                     else:
#                         error(self.pos, "'%s' is not a type identifier" % self.name)
#         if self.complex:
#             if not type.is_numeric or type.is_complex:
#                 error(self.pos, "can only complexify c numeric types")
#             type = PyrexTypes.CComplexType(type)
#             type.create_declaration_utility_code(env)
#         elif type is Builtin.complex_type:
#             # Special case: optimise builtin complex type into C's
#             # double complex.  The parser cannot do this (as for the
#             # normal scalar types) as the user may have redeclared the
#             # 'complex' type.  Testing for the exact type here works.
#             type = PyrexTypes.c_double_complex_type
#             type.create_declaration_utility_code(env)
#             self.complex = True
#         if type:
#             return type
#         else:
#             return PyrexTypes.error_type


from Cython.Compiler.Visitor import VisitorTransform
from Cython.Compiler.Nodes import CSimpleBaseTypeNode

class CDefToDefTransform(VisitorTransform):
    # Does not really turns cdefed function into defed function, it justs kills
    # the arguments and the return types of the functions, we rely on the
    # CodeWriter to get 'def' instead of 'cdef'
    visit_Node = VisitorTransform.recurse_to_children

    def visit_CFuncDefNode(self, node):
        oldbase_type = node.base_type
        node.base_type = CSimpleBaseTypeNode(0)
        node.base_type.name = None
        node.base_type.is_self_arg = False
        self.strip_args_types(node.declarator.args)
        return node

    def visit_DefNode(self, node):
        self.strip_args_types(node.args)
        return node

    def strip_args_types(self, args):
        for arg in args:
            oldbase_type = arg.base_type

# Path: Cython/Compiler/Visitor.py
# class VisitorTransform(TreeVisitor):
#     """
#     A tree transform is a base class for visitors that wants to do stream
#     processing of the structure (rather than attributes etc.) of a tree.
# 
#     It implements __call__ to simply visit the argument node.
# 
#     It requires the visitor methods to return the nodes which should take
#     the place of the visited node in the result tree (which can be the same
#     or one or more replacement). Specifically, if the return value from
#     a visitor method is:
# 
#     - [] or None; the visited node will be removed (set to None if an attribute and
#     removed if in a list)
#     - A single node; the visited node will be replaced by the returned node.
#     - A list of nodes; the visited nodes will be replaced by all the nodes in the
#     list. This will only work if the node was already a member of a list; if it
#     was not, an exception will be raised. (Typically you want to ensure that you
#     are within a StatListNode or similar before doing this.)
#     """
#     def visitchildren(self, parent, attrs=None):
#         result = self._visitchildren(parent, attrs)
#         for attr, newnode in result.iteritems():
#             if not type(newnode) is list:
#                 setattr(parent, attr, newnode)
#             else:
#                 # Flatten the list one level and remove any None
#                 newlist = []
#                 for x in newnode:
#                     if x is not None:
#                         if type(x) is list:
#                             newlist += x
#                         else:
#                             newlist.append(x)
#                 setattr(parent, attr, newlist)
#         return result
# 
#     def recurse_to_children(self, node):
#         self.visitchildren(node)
#         return node
# 
#     def __call__(self, root):
#         return self._visit(root)
# 
# Path: Cython/Compiler/Nodes.py
# class CSimpleBaseTypeNode(CBaseTypeNode):
#     # name             string
#     # module_path      [string]     Qualifying name components
#     # is_basic_c_type  boolean
#     # signed           boolean
#     # longness         integer
#     # complex          boolean
#     # is_self_arg      boolean      Is self argument of C method
#     # ##is_type_arg      boolean      Is type argument of class method
# 
#     child_attrs = []
#     arg_name = None   # in case the argument name was interpreted as a type
#     module_path = []
#     is_basic_c_type = False
#     complex = False
# 
#     def analyse(self, env, could_be_name = False):
#         # Return type descriptor.
#         #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
#         type = None
#         if self.is_basic_c_type:
#             type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
#             if not type:
#                 error(self.pos, "Unrecognised type modifier combination")
#         elif self.name == "object" and not self.module_path:
#             type = py_object_type
#         elif self.name is None:
#             if self.is_self_arg and env.is_c_class_scope:
#                 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
#                 type = env.parent_type
#             ## elif self.is_type_arg and env.is_c_class_scope:
#             ##     type = Builtin.type_type
#             else:
#                 type = py_object_type
#         else:
#             if self.module_path:
#                 scope = env.find_imported_module(self.module_path, self.pos)
#                 if scope:
#                     scope.fused_to_specific = env.fused_to_specific
#             else:
#                 scope = env
# 
#             if scope:
#                 if scope.is_c_class_scope:
#                     scope = scope.global_scope()
# 
#                 type = scope.lookup_type(self.name)
#                 if type is not None:
#                     pass
#                 elif could_be_name:
#                     if self.is_self_arg and env.is_c_class_scope:
#                         type = env.parent_type
#                     ## elif self.is_type_arg and env.is_c_class_scope:
#                     ##     type = Builtin.type_type
#                     else:
#                         type = py_object_type
#                     self.arg_name = self.name
#                 else:
#                     if self.templates:
#                         if not self.name in self.templates:
#                             error(self.pos, "'%s' is not a type identifier" % self.name)
#                         type = PyrexTypes.TemplatePlaceholderType(self.name)
#                     else:
#                         error(self.pos, "'%s' is not a type identifier" % self.name)
#         if self.complex:
#             if not type.is_numeric or type.is_complex:
#                 error(self.pos, "can only complexify c numeric types")
#             type = PyrexTypes.CComplexType(type)
#             type.create_declaration_utility_code(env)
#         elif type is Builtin.complex_type:
#             # Special case: optimise builtin complex type into C's
#             # double complex.  The parser cannot do this (as for the
#             # normal scalar types) as the user may have redeclared the
#             # 'complex' type.  Testing for the exact type here works.
#             type = PyrexTypes.c_double_complex_type
#             type.create_declaration_utility_code(env)
#             self.complex = True
#         if type:
#             return type
#         else:
#             return PyrexTypes.error_type


# Path: Cython/CTypesBackend/CDefToDefTransform.py
from Cython.Compiler.Visitor import VisitorTransform
from Cython.Compiler.Nodes import CSimpleBaseTypeNode


class CDefToDefTransform(VisitorTransform):
    # Does not really turns cdefed function into defed function, it justs kills
    # the arguments and the return types of the functions, we rely on the
    # CodeWriter to get 'def' instead of 'cdef'
    visit_Node = VisitorTransform.recurse_to_children

    def visit_CFuncDefNode(self, node):
        oldbase_type = node.base_type
        node.base_type = CSimpleBaseTypeNode(0)
        node.base_type.name = None
        node.base_type.is_self_arg = False
        self.strip_args_types(node.declarator.args)
        return node

    def visit_DefNode(self, node):
        self.strip_args_types(node.args)
        return node

    def strip_args_types(self, args):
        for arg in args:
            oldbase_type = arg.base_type

            arg.base_type = CSimpleBaseTypeNode(0)