# 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) ''' Defines classes that represent declarations found in C++ header files. ''' # version indicates the version of the declarations. Whenever a declaration # changes, this variable should be updated, so that the caches can be rebuilt # automatically version = '1.0' #============================================================================== # Declaration #============================================================================== class Declaration(object): '''Base class for all declarations. @ivar name: The name of the declaration. @ivar namespace: The namespace of the declaration. ''' def __init__(self, name, namespace): ''' @type name: string @param name: The name of this declaration @type namespace: string @param namespace: the full namespace where this declaration resides. ''' self.name = name self.namespace = namespace self.location = '', -1 # (filename, line) self.incomplete = False self.is_unique = True def FullName(self): ''' Returns the full qualified name: "boost::inner::Test" @rtype: string @return: The full name of the declaration. ''' namespace = self.namespace or '' if namespace and not namespace.endswith('::'): namespace += '::' return namespace + self.name def __repr__(self): return '' % (self.FullName(), id(self)) def __str__(self): return 'Declaration of %s' % self.FullName() #============================================================================== # Class #============================================================================== class Class(Declaration): ''' Represents a C++ class or struct. Iteration through it yields its members. @type abstract: bool @ivar abstract: if the class has any abstract methods. @type bases: tuple @ivar bases: tuple with L{Base} instances, representing the most direct inheritance. @type hierarchy: list @ivar hierarchy: a list of tuples of L{Base} instances, representing the entire hierarchy tree of this object. The first tuple is the parent classes, and the other ones go up in the hierarchy. ''' def __init__(self, name, namespace, members, abstract): Declaration.__init__(self, name, namespace) self.__members = members self.__member_names = {} self.abstract = abstract self.bases = () self.hierarchy = () self.operator = {} def __iter__(self): '''iterates through the class' members. ''' return iter(self.__members) def Constructors(self, publics_only=True): '''Returns a list of the constructors for this class. @rtype: list ''' constructors = [] for member in self: if isinstance(member, Constructor): if publics_only and member.visibility != Scope.public: continue constructors.append(member) return constructors def HasCopyConstructor(self): '''Returns true if this class has a public copy constructor. @rtype: bool ''' for cons in self.Constructors(): if cons.IsCopy(): return True return False def HasDefaultConstructor(self): '''Returns true if this class has a public default constructor. @rtype: bool ''' for cons in self.Constructors(): if cons.IsDefault(): return True return False def AddMember(self, member): if member.name in self.__member_names: member.is_unique = False for m in self: if m.name == member.name: m.is_unique = False else: member.is_unique = True self.__member_names[member.name] = 1 self.__members.append(member) if isinstance(member, ClassOperator): self.operator[member.name] = member def ValidMemberTypes(): return (NestedClass, Method, Constructor, Destructor, ClassVariable, ClassOperator, ConverterOperator, ClassEnumeration) ValidMemberTypes = staticmethod(ValidMemberTypes) #============================================================================== # NestedClass #============================================================================== class NestedClass(Class): '''The declaration of a class/struct inside another class/struct. @type class: string @ivar class: fullname of the class where this class is contained. @type visibility: L{Scope} @ivar visibility: the visibility of this class. ''' def __init__(self, name, class_, visib, members, abstract): Class.__init__(self, name, None, members, abstract) self.class_ = class_ self.visibility = visib def FullName(self): '''The full name of this class, like ns::outer::inner. @rtype: string ''' return '%s::%s' % (self.class_, self.name) #============================================================================== # Scope #============================================================================== class Scope: '''Used to represent the visibility of various members inside a class. @cvar public: public visibility @cvar private: private visibility @cvar protected: protected visibility ''' public = 'public' private = 'private' protected = 'protected' #============================================================================== # Base #============================================================================== class Base: '''Represents a base class of another class. @ivar _name: the full name of the base class. @ivar _visibility: the visibility of the derivation. ''' def __init__(self, name, visibility=Scope.public): self.name = name self.visibility = visibility #============================================================================== # Function #============================================================================== class Function(Declaration): '''The declaration of a function. @ivar _result: instance of L{Type} or None. @ivar _parameters: list of L{Type} instances. @ivar _throws: exception specifiers or None ''' def __init__(self, name, namespace, result, params, throws=None): Declaration.__init__(self, name, namespace) # the result type: instance of Type, or None (constructors) self.result = result # the parameters: instances of Type self.parameters = params # the exception specification self.throws = throws def Exceptions(self): if self.throws is None: return "" else: return " throw(%s)" % ', '.join ([x.FullName() for x in self.throws]) def PointerDeclaration(self, force=False): '''Returns a declaration of a pointer to this function. @param force: If True, returns a complete pointer declaration regardless if this function is unique or not. ''' if self.is_unique and not force: return '&%s' % self.FullName() else: result = self.result.FullName() params = ', '.join([x.FullName() for x in self.parameters]) return '(%s (*)(%s)%s)&%s' % (result, params, self.Exceptions(), self.FullName()) def MinArgs(self): min = 0 for arg in self.parameters: if arg.default is None: min += 1 return min minArgs = property(MinArgs) def MaxArgs(self): return len(self.parameters) maxArgs = property(MaxArgs) #============================================================================== # Operator #============================================================================== class Operator(Function): '''The declaration of a custom operator. Its name is the same as the operator name in C++, ie, the name of the declaration "operator+(..)" is "+". ''' def FullName(self): namespace = self.namespace or '' if not namespace.endswith('::'): namespace += '::' return namespace + 'operator' + self.name #============================================================================== # Method #============================================================================== class Method(Function): '''The declaration of a method. @ivar _visibility: the visibility of this method. @ivar _virtual: if this method is declared as virtual. @ivar _abstract: if this method is virtual but has no default implementation. @ivar _static: if this method is static. @ivar _class: the full name of the class where this method was declared. @ivar _const: if this method is declared as const. @ivar _throws: list of exception specificiers or None ''' def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const, throws=None): Function.__init__(self, name, None, result, params, throws) self.visibility = visib self.virtual = virtual self.abstract = abstract self.static = static self.class_ = class_ self.const = const def FullName(self): return self.class_ + '::' + self.name def PointerDeclaration(self, force=False): '''Returns a declaration of a pointer to this member function. @param force: If True, returns a complete pointer declaration regardless if this function is unique or not. ''' if self.static: # static methods are like normal functions return Function.PointerDeclaration(self, force) if self.is_unique and not force: return '&%s' % self.FullName() else: result = self.result.FullName() params = ', '.join([x.FullName() for x in self.parameters]) const = '' if self.const: const = 'const' return '(%s (%s::*)(%s) %s%s)&%s' %\ (result, self.class_, params, const, self.Exceptions(), self.FullName()) #============================================================================== # Constructor #============================================================================== class Constructor(Method): '''A class' constructor. ''' def __init__(self, name, class_, params, visib): Method.__init__(self, name, class_, None, params, visib, False, False, False, False) def IsDefault(self): '''Returns True if this constructor is a default constructor. ''' return len(self.parameters) == 0 and self.visibility == Scope.public def IsCopy(self): '''Returns True if this constructor is a copy constructor. ''' if len(self.parameters) != 1: return False param = self.parameters[0] class_as_param = self.parameters[0].name == self.class_ param_reference = isinstance(param, ReferenceType) is_public = self.visibility == Scope.public return param_reference and class_as_param and param.const and is_public def PointerDeclaration(self, force=False): return '' #============================================================================== # Destructor #============================================================================== class Destructor(Method): 'The destructor of a class.' def __init__(self, name, class_, visib, virtual): Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False) def FullName(self): return self.class_ + '::~' + self.name def PointerDeclaration(self, force=False): return '' #============================================================================== # ClassOperator #============================================================================== class ClassOperator(Method): 'A custom operator in a class.' def FullName(self): return self.class_ + '::operator ' + self.name #============================================================================== # ConverterOperator #============================================================================== class ConverterOperator(ClassOperator): 'An operator in the form "operator OtherClass()".' def FullName(self): return self.class_ + '::operator ' + self.result.FullName() #============================================================================== # Type #============================================================================== class Type(Declaration): '''Represents the type of a variable or parameter. @ivar _const: if the type is constant. @ivar _default: if this type has a default value associated with it. @ivar _volatile: if this type was declared with the keyword volatile. @ivar _restricted: if this type was declared with the keyword restricted. @ivar _suffix: Suffix to get the full type name. '*' for pointers, for example. ''' def __init__(self, name, const=False, default=None, suffix=''): Declaration.__init__(self, name, None) # whatever the type is constant or not self.const = const # used when the Type is a function argument self.default = default self.volatile = False self.restricted = False self.suffix = suffix def __repr__(self): if self.const: const = 'const ' else: const = '' return '' def FullName(self): if self.const: const = 'const ' else: const = '' return const + self.name + self.suffix #============================================================================== # ArrayType #============================================================================== class ArrayType(Type): '''Represents an array. @ivar min: the lower bound of the array, usually 0. Can be None. @ivar max: the upper bound of the array. Can be None. ''' def __init__(self, name, const, min, max): 'min and max can be None.' Type.__init__(self, name, const) self.min = min self.max = max #============================================================================== # ReferenceType #============================================================================== class ReferenceType(Type): '''A reference type.''' def __init__(self, name, const=False, default=None, expandRef=True, suffix=''): Type.__init__(self, name, const, default) if expandRef: self.suffix = suffix + '&' #============================================================================== # PointerType #============================================================================== class PointerType(Type): 'A pointer type.' def __init__(self, name, const=False, default=None, expandPointer=False, suffix=''): Type.__init__(self, name, const, default) if expandPointer: self.suffix = suffix + '*' #============================================================================== # FundamentalType #============================================================================== class FundamentalType(Type): 'One of the fundamental types, like int, void, etc.' def __init__(self, name, const=False, default=None): Type.__init__(self, name, const, default) #============================================================================== # FunctionType #============================================================================== class FunctionType(Type): '''A pointer to a function. @ivar _result: the return value @ivar _parameters: a list of Types, indicating the parameters of the function. @ivar _name: the name of the function. ''' def __init__(self, result, parameters): Type.__init__(self, '', False) self.result = result self.parameters = parameters self.name = self.FullName() def FullName(self): full = '%s (*)' % self.result.FullName() params = [x.FullName() for x in self.parameters] full += '(%s)' % ', '.join(params) return full #============================================================================== # MethodType #============================================================================== class MethodType(FunctionType): '''A pointer to a member function of a class. @ivar _class: The fullname of the class that the method belongs to. ''' def __init__(self, result, parameters, class_): self.class_ = class_ FunctionType.__init__(self, result, parameters) def FullName(self): full = '%s (%s::*)' % (self.result.FullName(), self.class_) params = [x.FullName() for x in self.parameters] full += '(%s)' % ', '.join(params) return full #============================================================================== # Variable #============================================================================== class Variable(Declaration): '''Represents a global variable. @type _type: L{Type} @ivar _type: The type of the variable. ''' def __init__(self, type, name, namespace): Declaration.__init__(self, name, namespace) self.type = type #============================================================================== # ClassVariable #============================================================================== class ClassVariable(Variable): '''Represents a class variable. @type _visibility: L{Scope} @ivar _visibility: The visibility of this variable within the class. @type _static: bool @ivar _static: Indicates if the variable is static. @ivar _class: Full name of the class that this variable belongs to. ''' def __init__(self, type, name, class_, visib, static): Variable.__init__(self, type, name, None) self.visibility = visib self.static = static self.class_ = class_ def FullName(self): return self.class_ + '::' + self.name #============================================================================== # Enumeration #============================================================================== class Enumeration(Declaration): '''Represents an enum. @type _values: dict of str => int @ivar _values: holds the values for this enum. ''' def __init__(self, name, namespace): Declaration.__init__(self, name, namespace) self.values = {} # dict of str => int def ValueFullName(self, name): '''Returns the full name for a value in the enum. ''' assert name in self.values namespace = self.namespace if namespace: namespace += '::' return namespace + name #============================================================================== # ClassEnumeration #============================================================================== class ClassEnumeration(Enumeration): '''Represents an enum inside a class. @ivar _class: The full name of the class where this enum belongs. @ivar _visibility: The visibility of this enum inside his class. ''' def __init__(self, name, class_, visib): Enumeration.__init__(self, name, None) self.class_ = class_ self.visibility = visib def FullName(self): return '%s::%s' % (self.class_, self.name) def ValueFullName(self, name): assert name in self.values return '%s::%s' % (self.class_, name) #============================================================================== # Typedef #============================================================================== class Typedef(Declaration): '''A Typedef declaration. @type _type: L{Type} @ivar _type: The type of the typedef. @type _visibility: L{Scope} @ivar _visibility: The visibility of this typedef. ''' def __init__(self, type, name, namespace): Declaration.__init__(self, name, namespace) self.type = type self.visibility = Scope.public #============================================================================== # Unknown #============================================================================== class Unknown(Declaration): '''A declaration that Pyste does not know how to handle. ''' def __init__(self, name): Declaration.__init__(self, name, None)