mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-03 03:39:27 +00:00
Add code in wrappers generator for reference handling in docstrings
This commit is contained in:
parent
5e077c08b4
commit
2a3a235634
3 changed files with 171 additions and 28 deletions
|
|
@ -480,6 +480,18 @@ class CParser(object):
|
|||
else:
|
||||
self.classesIndex[_class.name] = None
|
||||
|
||||
self.methodsIndex = {}
|
||||
for _class in self.cProject.classes:
|
||||
for funcname in _class.classMethods:
|
||||
self.methodsIndex[funcname] = None
|
||||
for funcname in _class.instanceMethods:
|
||||
self.methodsIndex[funcname] = None
|
||||
for _property in _class.properties.values():
|
||||
if _property.setter is not None:
|
||||
self.methodsIndex[_property.setter.name] = None
|
||||
if _property.getter is not None:
|
||||
self.methodsIndex[_property.getter.name] = None
|
||||
|
||||
name = NamespaceName()
|
||||
name.from_snake_case('linphone')
|
||||
|
||||
|
|
@ -507,9 +519,24 @@ class CParser(object):
|
|||
pass
|
||||
except Error as e:
|
||||
print('Could not parse \'{0}\' class: {1}'.format(_class.name, e.args[0]))
|
||||
|
||||
|
||||
|
||||
self._clean_all_indexes()
|
||||
self._fix_all_types()
|
||||
self._fix_all_docs()
|
||||
|
||||
def _clean_all_indexes(self):
|
||||
for index in [self.classesIndex, self.interfacesIndex, self.methodsIndex]:
|
||||
self._clean_index(index)
|
||||
|
||||
def _clean_index(self, index):
|
||||
keysToRemove = []
|
||||
for key in index.keys():
|
||||
if index[key] is None:
|
||||
keysToRemove.append(key)
|
||||
|
||||
for key in keysToRemove:
|
||||
del index[key]
|
||||
|
||||
def _class_is_refcountable(self, _class):
|
||||
if _class.name in self.forcedRefcountableClasses:
|
||||
|
|
@ -576,6 +603,14 @@ class CParser(object):
|
|||
else:
|
||||
raise Error('bctbx_list_t type without specified contained type')
|
||||
|
||||
def _fix_all_docs(self):
|
||||
for _class in self.classesIndex.values():
|
||||
if _class.briefDescription is not None:
|
||||
_class.briefDescription.resolve_all_references(self)
|
||||
for method in self.methodsIndex.values():
|
||||
if method.briefDescription is not None:
|
||||
method.briefDescription.resolve_all_references(self)
|
||||
|
||||
def parse_enum(self, cenum):
|
||||
if 'associatedTypedef' in dir(cenum):
|
||||
nameStr = cenum.associatedTypedef.name
|
||||
|
|
@ -750,6 +785,7 @@ class CParser(object):
|
|||
absArg = Argument(argName, aType)
|
||||
method.add_arguments(absArg)
|
||||
|
||||
self.methodsIndex[cfunction.name] = method
|
||||
return method
|
||||
|
||||
def parse_type(self, cType):
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ class Project:
|
|||
self.__events = []
|
||||
self.__functions = []
|
||||
self.classes = []
|
||||
self.docparser = metadoc.Parser()
|
||||
|
||||
def add(self, elem):
|
||||
if isinstance(elem, CClass):
|
||||
|
|
@ -387,7 +388,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
ev.deprecated = True
|
||||
ev.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
ev.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
ev.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
ev.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
return ev
|
||||
|
||||
|
|
@ -399,7 +400,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
e.deprecated = True
|
||||
e.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
e.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
e.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
e.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
enumvalues = node.findall("enumvalue[@prot='public']")
|
||||
for enumvalue in enumvalues:
|
||||
|
|
@ -422,7 +423,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
sm.deprecated = True
|
||||
sm.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
sm.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
sm.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
sm.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
return sm
|
||||
|
||||
|
|
@ -432,7 +433,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
s.deprecated = True
|
||||
s.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
s.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
s.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
s.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
structmembers = node.findall("sectiondef/memberdef[@kind='variable'][@prot='public']")
|
||||
for structmember in structmembers:
|
||||
|
|
@ -501,7 +502,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
f.deprecated = True
|
||||
f.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
f.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
f.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
f.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
return f
|
||||
else:
|
||||
|
|
@ -513,7 +514,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
td.deprecated = True
|
||||
td.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
td.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
td.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
td.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
return td
|
||||
return None
|
||||
|
|
@ -573,7 +574,7 @@ class Project:
|
|||
if deprecatedNode is not None:
|
||||
f.deprecated = True
|
||||
f.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip()
|
||||
f.briefDoc = metadoc.Description(node.find('./briefdescription'))
|
||||
f.briefDoc = self.docparser.parse_description(node.find('./briefdescription'))
|
||||
f.detailedDescription = self.__cleanDescription(node.find('./detaileddescription'))
|
||||
if f.briefDescription == '' and ''.join(f.detailedDescription.itertext()).strip() == '':
|
||||
return None
|
||||
|
|
|
|||
146
tools/metadoc.py
146
tools/metadoc.py
|
|
@ -16,45 +16,95 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
import abstractapi
|
||||
|
||||
|
||||
class Nil:
|
||||
pass
|
||||
|
||||
|
||||
class Reference:
|
||||
def __init__(self, name):
|
||||
self.cObjectName = name
|
||||
def __init__(self, cname):
|
||||
self.cname = cname
|
||||
self.relatedObject = None
|
||||
|
||||
|
||||
class ClassReference(Reference):
|
||||
def resolve(self, api):
|
||||
try:
|
||||
self.relatedObject = api.classesIndex[self.cname]
|
||||
except KeyError:
|
||||
print('doc reference pointing on an unknown object ({0})'.format(self.cname))
|
||||
|
||||
|
||||
class FunctionReference(Reference):
|
||||
def resolve(self, api):
|
||||
try:
|
||||
self.relatedObject = api.methodsIndex[self.cname]
|
||||
except KeyError:
|
||||
print('doc reference pointing on an unknown object ({0})'.format(self.cname))
|
||||
|
||||
|
||||
class Paragraph:
|
||||
def __init__(self, node=None):
|
||||
def __init__(self):
|
||||
self.parts = []
|
||||
if node is not None:
|
||||
self.parse_doxygen_node(node)
|
||||
|
||||
def parse_doxygen_node(self, node):
|
||||
for partNode in node.iter():
|
||||
text = partNode.text
|
||||
if text is not None:
|
||||
self.parts.append(text)
|
||||
if partNode is not node:
|
||||
tail = partNode.tail
|
||||
if tail is not None:
|
||||
self.parts.append(tail)
|
||||
def resolve_all_references(self, api):
|
||||
for part in self.parts:
|
||||
if isinstance(part, Reference):
|
||||
part.resolve(api)
|
||||
|
||||
|
||||
class Description:
|
||||
def __init__(self, node=None):
|
||||
def __init__(self):
|
||||
self.paragraphs = []
|
||||
if node is not None:
|
||||
self.parse_doxygen_node(node)
|
||||
|
||||
def parse_doxygen_node(self, node):
|
||||
def resolve_all_references(self, api):
|
||||
for paragraph in self.paragraphs:
|
||||
paragraph.resolve_all_references(api)
|
||||
|
||||
|
||||
class Parser:
|
||||
def parse_description(self, node):
|
||||
desc = Description()
|
||||
for paraNode in node.findall('./para'):
|
||||
self.paragraphs.append(Paragraph(paraNode))
|
||||
desc.paragraphs.append(self._parse_paragraph(paraNode))
|
||||
return desc
|
||||
|
||||
def _parse_paragraph(self, node):
|
||||
paragraph = Paragraph()
|
||||
for partNode in node.iter():
|
||||
if partNode is node:
|
||||
text = partNode.text
|
||||
if text is not None:
|
||||
paragraph.parts.append(text)
|
||||
else:
|
||||
if partNode.tag == 'ref':
|
||||
ref = self._parse_reference(partNode)
|
||||
if ref is not None:
|
||||
paragraph.parts.append(ref)
|
||||
else:
|
||||
text = partNode.text
|
||||
if text is not None:
|
||||
paragraph.parts.append(text)
|
||||
|
||||
tail = partNode.tail
|
||||
if tail is not None:
|
||||
paragraph.parts.append(tail)
|
||||
|
||||
return paragraph
|
||||
|
||||
def _parse_reference(self, node):
|
||||
if node.text.endswith('()'):
|
||||
return FunctionReference(node.text[0:-2])
|
||||
else:
|
||||
return ClassReference(node.text)
|
||||
|
||||
|
||||
class Translator:
|
||||
def __init__(self):
|
||||
self.textWidth = 80
|
||||
|
||||
def translate(self, description):
|
||||
if description is None:
|
||||
return None
|
||||
|
|
@ -63,21 +113,77 @@ class Translator:
|
|||
for para in description.paragraphs:
|
||||
if para is not description.paragraphs[0]:
|
||||
lines.append('')
|
||||
lines.append(''.join(para.parts))
|
||||
lines.append(self._translate_paragraph(para))
|
||||
|
||||
self._tag_as_brief(lines)
|
||||
lines = self._crop_text(lines, self.textWidth)
|
||||
|
||||
translatedDoc = {'lines': []}
|
||||
for line in lines:
|
||||
translatedDoc['lines'].append({'line': line})
|
||||
|
||||
return translatedDoc
|
||||
|
||||
def _translate_paragraph(self, para):
|
||||
strPara = ''
|
||||
for part in para.parts:
|
||||
if isinstance(part, str):
|
||||
strPara += part
|
||||
elif isinstance(part, Reference):
|
||||
try:
|
||||
strPara += self._translate_reference(part)
|
||||
except ReferenceTranslationError as e:
|
||||
print('could not translate one reference in docstrings ({0})'.format(e.args[0]))
|
||||
strPara += Translator._translate_reference(self, part)
|
||||
else:
|
||||
raise TypeError('untranslatable paragraph element ({0})'.format(part))
|
||||
|
||||
return strPara
|
||||
|
||||
def _translate_reference(self, ref):
|
||||
if isinstance(ref, FunctionReference):
|
||||
return ref.cname + '()'
|
||||
else:
|
||||
return ref.cname
|
||||
|
||||
def _crop_text(self, inputLines, width):
|
||||
outputLines = []
|
||||
for line in inputLines:
|
||||
outputLines += self._split_line(line, width)
|
||||
return outputLines
|
||||
|
||||
def _split_line(self, line, width):
|
||||
lines = []
|
||||
while len(line) > width:
|
||||
cutIndex = line.rfind(' ', 0, width)
|
||||
if cutIndex != -1:
|
||||
lines.append(line[0:cutIndex])
|
||||
line = line[cutIndex+1:]
|
||||
else:
|
||||
cutIndex = width
|
||||
lines.append(line[0:cutIndex])
|
||||
line = line[cutIndex:]
|
||||
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
|
||||
class ReferenceTranslationError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
class DoxygenCppTranslator(Translator):
|
||||
def _tag_as_brief(self, lines):
|
||||
if len(lines) > 0:
|
||||
lines[0] = '@brief ' + lines[0]
|
||||
|
||||
def _translate_reference(self, ref):
|
||||
if isinstance(ref.relatedObject, (abstractapi.Class, abstractapi.Enum)):
|
||||
return '#' + ref.relatedObject.name.to_c()
|
||||
elif isinstance(ref.relatedObject, abstractapi.Method):
|
||||
return ref.relatedObject.name.to_c() + '()'
|
||||
else:
|
||||
raise ReferenceTranslationError(ref.cname)
|
||||
|
||||
|
||||
class SandcastleCSharpTranslator(Translator):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue