# Copyright Bruno da Silva de Oliveira 2003. Use, modification and 
# distribution is subject to the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at 
# http://www.boost.org/LICENSE_1_0.txt)

from declarations import *
# try to use cElementTree if avaiable
try:
    from cElementTree import ElementTree    
except ImportError:
    # fall back to the normal elementtree
    from elementtree.ElementTree import ElementTree
from xml.parsers.expat import ExpatError
from copy import deepcopy
from utils import enumerate


#==============================================================================
# Exceptions
#==============================================================================
class InvalidXMLError(Exception): pass

class ParserError(Exception): pass

class InvalidContextError(ParserError): pass


#==============================================================================
# GCCXMLParser
#==============================================================================
class GCCXMLParser(object):
    'Parse a GCC_XML file and extract the top-level declarations.'
    
    interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0}
    
    def Parse(self, filename):
        self.elements = self.GetElementsFromXML(filename)
        # high level declarations
        self.declarations = []
        self._names = {}
        # parse the elements
        for id in self.elements:
            element, decl = self.elements[id]
            if decl is None: 
                try:
                    self.ParseElement(id, element)
                except InvalidContextError:
                    pass # ignore those nodes with invalid context 
                         # (workaround gccxml bug)
         

    def Declarations(self):
        return self.declarations


    def AddDecl(self, decl):
        if decl.FullName() in self._names:
            decl.is_unique= False
            for d in self.declarations:
                if d.FullName() == decl.FullName():
                    d.is_unique = False
        self._names[decl.FullName()] = 0
        self.declarations.append(decl)

        
    def ParseElement(self, id, element):
        method = 'Parse' + element.tag
        if hasattr(self, method):
            func = getattr(self, method)
            func(id, element)
        else:
            self.ParseUnknown(id, element)

            
    def GetElementsFromXML(self,filename):
        'Extracts a dictionary of elements from the gcc_xml file.'
        
        tree = ElementTree()
        try:
            tree.parse(filename)
        except ExpatError:
            raise InvalidXMLError, 'Not a XML file: %s' % filename

        root = tree.getroot()
        if root.tag != 'GCC_XML':
            raise InvalidXMLError, 'Not a valid GCC_XML file'

        # build a dictionary of id -> element, None
        elementlist = root.getchildren()
        elements = {}
        for element in elementlist:
            id = element.get('id')
            if id:
                elements[id] = element, None
        return elements


    def GetDecl(self, id):
        if id not in self.elements:
            if id == '_0':
                raise InvalidContextError, 'Invalid context found in the xml file.'
            else: 
                msg = 'ID not found in elements: %s' % id
                raise ParserError, msg

        elem, decl = self.elements[id]
        if decl is None:
            self.ParseElement(id, elem)
            elem, decl = self.elements[id]
            if decl is None:
                raise ParserError, 'Could not parse element: %s' % elem.tag
        return decl
    

    def GetType(self, id):
        def Check(id, feature):
            pos = id.find(feature)
            if pos != -1:
                id = id[:pos] + id[pos+1:]
                return True, id
            else:
                return False, id
        const, id = Check(id, 'c')
        volatile, id = Check(id, 'v')
        restricted, id = Check(id, 'r')
        decl = self.GetDecl(id)
        if isinstance(decl, Type):
            res = deepcopy(decl)
            if const:
                res.const = const
            if volatile: 
                res.volatile = volatile
            if restricted:
                res.restricted = restricted
        else:
            res = Type(decl.FullName(), const)
            res.volatile = volatile
            res.restricted = restricted
        return res            
        
                
    def GetLocation(self, location):
        file, line = location.split(':')
        file = self.GetDecl(file)
        return file, int(line)

        
    def Update(self, id, decl):
        element, _ = self.elements[id]
        self.elements[id] = element, decl

        
    def ParseUnknown(self, id, element):
        name = '__Unknown_Element_%s' % id
        decl = Unknown(name)
        self.Update(id, decl)
        
        
    def ParseNamespace(self, id, element):
        namespace = element.get('name')
        context = element.get('context')
        if context:
            outer = self.GetDecl(context)
            if not outer.endswith('::'):
                outer += '::'
            namespace = outer + namespace
        if namespace.startswith('::'):
            namespace = namespace[2:]
        self.Update(id, namespace)


    def ParseFile(self, id, element):
        filename = element.get('name')
        self.Update(id, filename)

        
    def ParseVariable(self, id, element):
        # in gcc_xml, a static Field is declared as a Variable, so we check
        # this and call the Field parser.
        context = self.GetDecl(element.get('context'))
        if isinstance(context, Class):
            self.ParseField(id, element)
            elem, decl = self.elements[id]
            decl.static = True
        else:
            namespace = context
            name = element.get('name')                    
            type_ = self.GetType(element.get('type'))
            location = self.GetLocation(element.get('location'))
            variable = Variable(type_, name, namespace)
            variable.location = location
            self.AddDecl(variable)
            self.Update(id, variable)
        

    def GetArguments(self, element):
        args = []
        for child in element:
            if child.tag == 'Argument':
                type = self.GetType(child.get('type'))
                type.default = child.get('default')                
                args.append(type)
        return args

    
    def GetExceptions(self, exception_list):
        if exception_list is None:
            return None

        exceptions = []
        for t in exception_list.split():
            exceptions.append(self.GetType(t))

        return exceptions


    def ParseFunction(self, id, element, functionType=Function):
        '''functionType is used because a Operator is identical to a normal 
        function, only the type of the function changes.'''
        name = element.get('name')
        returns = self.GetType(element.get('returns'))
        namespace = self.GetDecl(element.get('context'))
        location = self.GetLocation(element.get('location'))
        params = self.GetArguments(element)
        incomplete = bool(int(element.get('incomplete', 0)))
        throws = self.GetExceptions(element.get('throw', None))
        function = functionType(name, namespace, returns, params, throws) 
        function.location = location
        self.AddDecl(function)
        self.Update(id, function)


    def ParseOperatorFunction(self, id, element):
        self.ParseFunction(id, element, Operator)

        
    def GetHierarchy(self, bases):       
        '''Parses the string "bases" from the xml into a list of tuples of Base
        instances. The first tuple is the most direct inheritance, and then it
        goes up in the hierarchy. 
        '''

        if bases is None:
            return []
        base_names = bases.split()
        this_level = []      
        next_levels = []
        for base in base_names:
            # get the visibility
            split = base.split(':')
            if len(split) == 2:
                visib = split[0]
                base = split[1]
            else:
                visib = Scope.public                            
            decl = self.GetDecl(base) 
            if not isinstance(decl, Class):
                # on windows, there are some classes which "bases" points to an
                # "Unimplemented" tag, but we are not interested in this classes
                # anyway
                continue
            base = Base(decl.FullName(), visib)
            this_level.append(base)
            # normalize with the other levels
            for index, level in enumerate(decl.hierarchy):
                if index < len(next_levels):
                    next_levels[index] = next_levels[index] + level
                else:
                    next_levels.append(level)
        hierarchy = []
        if this_level:
            hierarchy.append(tuple(this_level))
        if next_levels:
            hierarchy.extend(next_levels)
        return hierarchy

        
    def GetMembers(self, member_list):
        # members must be a string with the ids of the members
        if member_list is None:
            return []
        members = []
        for member in member_list.split():
            decl = self.GetDecl(member)
            if type(decl) in Class.ValidMemberTypes():
                members.append(decl) 
        return members


    def ParseClass(self, id, element):
        name = element.get('name')
        abstract = bool(int(element.get('abstract', '0')))
        location = self.GetLocation(element.get('location'))
        context = self.GetDecl(element.get('context'))
        incomplete = bool(int(element.get('incomplete', 0)))
        if isinstance(context, str): 
            class_ = Class(name, context, [], abstract)
        else:
            # a nested class
            visib = element.get('access', Scope.public)
            class_ = NestedClass(
                name, context.FullName(), visib, [], abstract)
        class_.incomplete = incomplete
        # we have to add the declaration of the class before trying        
        # to parse its members and bases, to avoid recursion.
        self.AddDecl(class_)
        class_.location = location
        self.Update(id, class_)       
        # now we can get the members and the bases
        class_.hierarchy = self.GetHierarchy(element.get('bases'))        
        if class_.hierarchy:
            class_.bases = class_.hierarchy[0]
        members = self.GetMembers(element.get('members'))
        for member in members:
            class_.AddMember(member)


    def ParseStruct(self, id, element):
        self.ParseClass(id, element)


    FUNDAMENTAL_RENAME = {
        'long long int' : 'boost::int64_t',
        'long long unsigned int' : 'boost::uint64_t',
    }

    def ParseFundamentalType(self, id, element):
        name = element.get('name')
        name = self.FUNDAMENTAL_RENAME.get(name, name)
        type_ = FundamentalType(name)
        self.Update(id, type_)


    def ParseArrayType(self, id, element):
        type = self.GetType(element.get('type'))
        min = element.get('min')
        max = element.get('max')
        array = ArrayType(type.name, type.const, min, max)
        self.Update(id, array)

        
    def ParseReferenceType(self, id, element):
        type = self.GetType(element.get('type'))
        expand = not isinstance(type, FunctionType)
        ref = ReferenceType(type.name, type.const, None, expand, type.suffix)
        self.Update(id, ref)
        
        
    def ParsePointerType(self, id, element):
        type = self.GetType(element.get('type'))
        expand = not isinstance(type, FunctionType)
        ref = PointerType(type.name, type.const, None, expand, type.suffix)
        self.Update(id, ref)
        
        
    def ParseFunctionType(self, id, element):
        result = self.GetType(element.get('returns'))
        args = self.GetArguments(element)
        func = FunctionType(result, args)
        self.Update(id, func)


    def ParseMethodType(self, id, element):
        class_ = self.GetDecl(element.get('basetype')).FullName()
        result = self.GetType(element.get('returns'))
        args = self.GetArguments(element)
        method = MethodType(result, args, class_)
        self.Update(id, method)

        
    def ParseField(self, id, element):
        name = element.get('name')
        visib = element.get('access', Scope.public)
        classname = self.GetDecl(element.get('context')).FullName()
        type_ = self.GetType(element.get('type'))
        static = bool(int(element.get('extern', '0')))
        location = self.GetLocation(element.get('location'))
        var = ClassVariable(type_, name, classname, visib, static)
        var.location = location
        self.Update(id, var)


    def ParseMethod(self, id, element, methodType=Method):
        name = element.get('name')
        result = self.GetType(element.get('returns'))
        classname = self.GetDecl(element.get('context')).FullName()
        visib = element.get('access', Scope.public)
        static = bool(int(element.get('static', '0')))
        virtual = bool(int(element.get('virtual', '0')))
        abstract = bool(int(element.get('pure_virtual', '0')))
        const = bool(int(element.get('const', '0')))
        location = self.GetLocation(element.get('location'))
        throws = self.GetExceptions(element.get('throw', None)) 
        params = self.GetArguments(element)
        method = methodType(
            name, classname, result, params, visib, virtual, abstract, static, const, throws)
        method.location = location
        self.Update(id, method)


    def ParseOperatorMethod(self, id, element):
        self.ParseMethod(id, element, ClassOperator)

        
    def ParseConstructor(self, id, element):
        name = element.get('name')
        visib = element.get('access', Scope.public)
        classname = self.GetDecl(element.get('context')).FullName()
        location = self.GetLocation(element.get('location'))
        params = self.GetArguments(element)
        artificial = element.get('artificial', False)        
        ctor = Constructor(name, classname, params, visib)
        ctor.location = location
        self.Update(id, ctor)


    def ParseDestructor(self, id, element):
        name = element.get('name')
        visib = element.get('access', Scope.public)
        classname = self.GetDecl(element.get('context')).FullName()
        virtual = bool(int(element.get('virtual', '0')))
        location = self.GetLocation(element.get('location'))
        des = Destructor(name, classname, visib, virtual)
        des.location = location
        self.Update(id, des)


    def ParseConverter(self, id, element):
        self.ParseMethod(id, element, ConverterOperator)


    def ParseTypedef(self, id, element):
        name = element.get('name')
        type = self.GetType(element.get('type'))        
        context = self.GetDecl(element.get('context'))
        if isinstance(context, Class):
            context = context.FullName()
        typedef = Typedef(type, name, context)
        self.Update(id, typedef)
        self.AddDecl(typedef)


    def ParseEnumeration(self, id, element):
        name = element.get('name')
        location = self.GetLocation(element.get('location'))
        context = self.GetDecl(element.get('context'))
        incomplete = bool(int(element.get('incomplete', 0))) 
        if isinstance(context, str):
            enum = Enumeration(name, context)
        else:
            visib = element.get('access', Scope.public)
            enum = ClassEnumeration(name, context.FullName(), visib)
        self.AddDecl(enum)
        enum.location = location
        for child in element:
            if child.tag == 'EnumValue':
                name = child.get('name')
                value = int(child.get('init'))
                enum.values[name] = value
        enum.incomplete = incomplete
        self.Update(id, enum)



def ParseDeclarations(filename):
    'Returns a list of the top declarations found in the gcc_xml file.'
        
    parser = GCCXMLParser() 
    parser.Parse(filename)
    return parser.Declarations()


if __name__ == '__main__':
    ParseDeclarations(r'D:\Programming\Libraries\boost-cvs\boost\libs\python\pyste\example\test.xml')
