Add support for non-ref-counted interface classes (issue #2090)

This commit is contained in:
Marshall Greenblatt
2017-02-07 16:25:11 -05:00
parent 9dd0ca2661
commit 07ba48b082
98 changed files with 6369 additions and 1825 deletions

View File

@ -94,6 +94,12 @@ def wrap_code(code, indent = ' ', maxchars = 80, splitchars = '(=,'):
return output
def is_base_class(clsname):
""" Returns true if |clsname| is a known base (root) class in the object
hierarchy.
"""
return clsname == 'CefBase' or clsname == 'CefBaseScoped'
def get_capi_file_name(cppname):
""" Convert a C++ header file name to a C API header file name. """
return cppname[:-2]+'_capi.h'
@ -302,7 +308,7 @@ def format_translation_includes(header, body):
list = sorted(set(p.findall(body)))
for item in list:
directory = ''
if item != 'CefBase':
if not is_base_class(item):
cls = header.get_class(item)
dir = cls.get_file_directory()
if not dir is None:
@ -315,7 +321,7 @@ def format_translation_includes(header, body):
list = sorted(set(p.findall(body)))
for item in list:
directory = ''
if item != 'CefBase':
if not is_base_class(item):
cls = header.get_class(item)
dir = cls.get_file_directory()
if not dir is None:
@ -383,9 +389,9 @@ _cre_cfnameorpath = '([A-Za-z0-9_\/]{1,})'
# regex for matching function return values
_cre_retval = '([A-Za-z0-9_<>:,\*\&]{1,})'
# regex for matching typedef value and name combination
_cre_typedef = '([A-Za-z0-9_<>:,\*\& ]{1,})'
_cre_typedef = '([A-Za-z0-9_<>:,\*\&\s]{1,})'
# regex for matching function return value and name combination
_cre_func = '([A-Za-z][A-Za-z0-9_<>:,\*\& ]{1,})'
_cre_func = '([A-Za-z][A-Za-z0-9_<>:,\*\&\s]{1,})'
# regex for matching virtual function modifiers
_cre_vfmod = '([A-Za-z0-9_]{0,})'
# regex for matching arbitrary whitespace
@ -554,8 +560,8 @@ class obj_header:
pos = value.rfind(' ')
if pos < 0:
raise Exception('Invalid typedef: '+value)
alias = value[pos+1:]
value = value[:pos]
alias = value[pos+1:].strip()
value = value[:pos].strip()
self.typedefs.append(obj_typedef(self, filename, value, alias))
# extract global functions
@ -592,7 +598,7 @@ class obj_header:
# build the class objects
for attrib, name, parent_name, body in list:
comment = get_comment(data, name+' : public')
comment = get_comment(data, name+' :')
validate_comment(filename, name, comment)
self.classes.append(
obj_class(self, filename, attrib, name, parent_name, body,
@ -673,6 +679,20 @@ class obj_header:
result.append(cls.get_name())
return result
def get_base_class_name(self, classname):
""" Returns the base (root) class name for |classname|. """
cur_cls = self.get_class(classname)
while True:
parent_name = cur_cls.get_parent_name()
if is_base_class(parent_name):
return parent_name
else:
parent_cls = self.get_class(parent_name)
if parent_cls is None:
break
cur_cls = self.get_class(parent_name)
return None
def get_types(self, list):
""" Return a dictionary mapping data types to analyzed values. """
for cls in self.typedefs:
@ -695,7 +715,7 @@ class obj_header:
def get_defined_structs(self):
""" Return a list of already defined structure names. """
return ['cef_print_info_t', 'cef_window_info_t', 'cef_base_t']
return ['cef_print_info_t', 'cef_window_info_t', 'cef_base_t', 'cef_base_scoped_t']
def get_capi_translations(self):
""" Return a dictionary that maps C++ terminology to C API terminology.
@ -760,8 +780,8 @@ class obj_class:
pos = value.rfind(' ')
if pos < 0:
raise Exception('Invalid typedef: '+value)
alias = value[pos+1:]
value = value[:pos]
alias = value[pos+1:].strip()
value = value[:pos].strip()
self.typedefs.append(obj_typedef(self, filename, value, alias))
# extract static functions
@ -856,16 +876,16 @@ class obj_class:
def has_parent(self, parent_name):
""" Returns true if this class has the specified class anywhere in its
inheritance hierarchy. """
# Every class has CefBase as the top-most parent.
if parent_name == 'CefBase' or parent_name == self.parent_name:
# Every class has a known base class as the top-most parent.
if is_base_class(parent_name) or parent_name == self.parent_name:
return True
if self.parent_name == 'CefBase':
if is_base_class(self.parent_name):
return False
cur_cls = self.parent.get_class(self.parent_name)
while True:
cur_parent_name = cur_cls.get_parent_name()
if cur_parent_name == 'CefBase':
if is_base_class(cur_parent_name):
break
elif cur_parent_name == parent_name:
return True
@ -1214,7 +1234,7 @@ class obj_function:
this_is_library_side = True
header = self.parent
if other_class_name == 'CefBase':
if is_base_class(other_class_name):
other_is_library_side = False
else:
other_class = header.get_class(other_class_name)
@ -1386,17 +1406,17 @@ class obj_argument:
return 'string_byref_const'
return 'string_byref'
# refptr type
if self.type.is_result_refptr():
same_side = self.parent.is_same_side(self.type.get_refptr_type())
# *ptr type
if self.type.is_result_ptr():
prefix = self.type.get_result_ptr_type_prefix()
same_side = self.parent.is_same_side(self.type.get_ptr_type())
if self.type.is_byref():
if same_side:
return 'refptr_same_byref'
return 'refptr_diff_byref'
return prefix + 'ptr_same_byref'
return prefix + 'ptr_diff_byref'
if same_side:
return 'refptr_same'
return 'refptr_diff'
return prefix + 'ptr_same'
return prefix + 'ptr_diff'
if self.type.is_result_vector():
# all vector types must be passed by reference
@ -1421,17 +1441,17 @@ class obj_argument:
return 'bool_vec_byref_const'
return 'bool_vec_byref'
if self.type.is_result_vector_refptr():
# refptr vector types
same_side = self.parent.is_same_side(self.type.get_refptr_type())
if self.type.is_result_vector_ptr():
# *ptr vector types
prefix = self.type.get_result_vector_ptr_type_prefix()
same_side = self.parent.is_same_side(self.type.get_ptr_type())
if self.type.is_const():
if same_side:
return 'refptr_vec_same_byref_const'
return 'refptr_vec_diff_byref_const'
return prefix + 'ptr_vec_same_byref_const'
return prefix + 'ptr_vec_diff_byref_const'
if same_side:
return 'refptr_vec_same_byref'
return 'refptr_vec_diff_byref'
return prefix + 'ptr_vec_same_byref'
return prefix + 'ptr_vec_diff_byref'
# string single map type
if self.type.is_result_map_single():
@ -1476,11 +1496,12 @@ class obj_argument:
if self.type.is_result_string():
return 'string'
if self.type.is_result_refptr():
if self.parent.is_same_side(self.type.get_refptr_type()):
return 'refptr_same'
if self.type.is_result_ptr():
prefix = self.type.get_result_ptr_type_prefix()
if self.parent.is_same_side(self.type.get_ptr_type()):
return prefix + 'ptr_same'
else:
return 'refptr_diff'
return prefix + 'ptr_diff'
return 'invalid'
@ -1509,8 +1530,14 @@ class obj_argument:
if for_capi:
return 'NULL'
return 'CefString()'
elif type == 'refptr_same' or type == 'refptr_diff':
elif type == 'refptr_same' or type == 'refptr_diff' or \
type == 'rawptr_same' or type == 'rawptr_diff':
return 'NULL'
elif type == 'ownptr_same' or type == 'ownptr_diff':
if for_capi:
return 'NULL'
else:
return 'CefOwnPtr<'+self.type.get_ptr_type()+'>()'
return ''
@ -1522,7 +1549,7 @@ class obj_analysis:
self.result_type = 'unknown'
self.result_value = None
self.result_default = None
self.refptr_type = None
self.ptr_type = None
# parse the argument string
partlist = string.split(string.strip(value))
@ -1626,8 +1653,8 @@ class obj_analysis:
if not basic is None:
self.result_type = basic['result_type']
self.result_value = basic['result_value']
if 'refptr_type' in basic:
self.refptr_type = basic['refptr_type']
if 'ptr_type' in basic:
self.ptr_type = basic['ptr_type']
if 'result_default' in basic:
self.result_default = basic['result_default']
return True
@ -1664,7 +1691,27 @@ class obj_analysis:
return {
'result_type' : 'refptr',
'result_value' : get_capi_name(list[0], True)+'*',
'refptr_type' : list[0]
'ptr_type' : list[0]
}
# check for CEF owned pointers
p = re.compile('^CefOwnPtr<(.*?)>$', re.DOTALL)
list = p.findall(value)
if len(list) == 1:
return {
'result_type' : 'ownptr',
'result_value' : get_capi_name(list[0], True)+'*',
'ptr_type' : list[0]
}
# check for CEF raw pointers
p = re.compile('^CefRawPtr<(.*?)>$', re.DOTALL)
list = p.findall(value)
if len(list) == 1:
return {
'result_type' : 'rawptr',
'result_value' : get_capi_name(list[0], True)+'*',
'ptr_type' : list[0]
}
# check for CEF structure types
@ -1695,13 +1742,13 @@ class obj_analysis:
""" Return the C++ type. """
return self.type
def get_refptr_type(self):
def get_ptr_type(self):
""" Return the C++ class type referenced by a CefRefPtr. """
if self.is_result_vector() and self.is_result_vector_refptr():
if self.is_result_vector() and self.is_result_vector_ptr():
# return the vector RefPtr type
return self.result_value[0]['refptr_type']
return self.result_value[0]['ptr_type']
# return the basic RefPtr type
return self.refptr_type
return self.ptr_type
def get_vector_type(self):
""" Return the C++ class type referenced by a std::vector. """
@ -1743,16 +1790,17 @@ class obj_analysis:
""" Return the default value fo the basic type. """
return self.result_default
def is_result_refptr(self):
""" Returns true if this is a reference pointer type. """
return (self.result_type == 'refptr')
def is_result_ptr(self):
""" Returns true if this is a *Ptr type. """
return self.is_result_refptr() or self.is_result_ownptr() or \
self.is_result_rawptr()
def get_result_refptr_type_root(self):
""" Return the refptr type structure name. """
def get_result_ptr_type_root(self):
""" Return the *Ptr type structure name. """
return self.result_value[:-1]
def get_result_refptr_type(self, defined_structs = []):
""" Return the refptr type. """
def get_result_ptr_type(self, defined_structs = []):
""" Return the *Ptr type. """
result = ''
if not self.result_value[:-1] in defined_structs:
result += 'struct _'
@ -1761,6 +1809,28 @@ class obj_analysis:
result += '*'
return result
def get_result_ptr_type_prefix(self):
""" Returns the *Ptr type prefix. """
if self.is_result_refptr():
return 'ref'
if self.is_result_ownptr():
return 'own'
if self.is_result_rawptr():
return 'raw'
raise Exception('Not a pointer type')
def is_result_refptr(self):
""" Returns true if this is a RefPtr type. """
return (self.result_type == 'refptr')
def is_result_ownptr(self):
""" Returns true if this is a OwnPtr type. """
return (self.result_type == 'ownptr')
def is_result_rawptr(self):
""" Returns true if this is a RawPtr type. """
return (self.result_type == 'rawptr')
def is_result_struct(self):
""" Returns true if this is a structure type. """
return (self.result_type == 'structure')
@ -1816,10 +1886,34 @@ class obj_analysis:
""" Returns true if this is a string vector. """
return self.result_value[0]['result_type'] == 'simple'
def is_result_vector_ptr(self):
""" Returns true if this is a *Ptr vector. """
return self.is_result_vector_refptr() or \
self.is_result_vector_ownptr() or \
self.is_result_vector_rawptr()
def get_result_vector_ptr_type_prefix(self):
""" Returns the *Ptr type prefix. """
if self.is_result_vector_refptr():
return 'ref'
if self.is_result_vector_ownptr():
return 'own'
if self.is_result_vector_rawptr():
return 'raw'
raise Exception('Not a pointer type')
def is_result_vector_refptr(self):
""" Returns true if this is a string vector. """
""" Returns true if this is a RefPtr vector. """
return self.result_value[0]['result_type'] == 'refptr'
def is_result_vector_ownptr(self):
""" Returns true if this is a OwnPtr vector. """
return self.result_value[0]['result_type'] == 'ownptr'
def is_result_vector_rawptr(self):
""" Returns true if this is a RawPtr vector. """
return self.result_value[0]['result_type'] == 'rawptr'
def get_result_vector_type_root(self):
""" Return the vector structure or basic type name. """
return self.result_value[0]['result_value']
@ -1844,7 +1938,7 @@ class obj_analysis:
str += ' const'
str += '*'
result['value'] = str
elif type == 'refptr':
elif type == 'refptr' or type == 'ownptr' or type == 'rawptr':
str = ''
if not value[:-1] in defined_structs:
str += 'struct _'
@ -1897,8 +1991,8 @@ class obj_analysis:
format = 'single'
if self.is_result_simple():
result += self.get_result_simple_type()
elif self.is_result_refptr():
result += self.get_result_refptr_type(defined_structs)
elif self.is_result_ptr():
result += self.get_result_ptr_type(defined_structs)
elif self.is_result_struct():
result += self.get_result_struct_type(defined_structs)
elif self.is_result_string():