mirror of
https://github.com/boostorg/python.git
synced 2026-01-22 05:22:45 +00:00
654 lines
21 KiB
Python
654 lines
21 KiB
Python
# 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 '<Declaration %s at %s>' % (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 '<Type ' + const + self.name + '>'
|
|
|
|
|
|
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)
|