summaryrefslogtreecommitdiff
path: root/libs/python/pyste/src/Pyste/declarations.py
diff options
context:
space:
mode:
Diffstat (limited to 'libs/python/pyste/src/Pyste/declarations.py')
-rw-r--r--libs/python/pyste/src/Pyste/declarations.py653
1 files changed, 653 insertions, 0 deletions
diff --git a/libs/python/pyste/src/Pyste/declarations.py b/libs/python/pyste/src/Pyste/declarations.py
new file mode 100644
index 000000000..6eff97dc5
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/declarations.py
@@ -0,0 +1,653 @@
+# 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)