Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
2a3a2356
Commit
2a3a2356
authored
Apr 25, 2017
by
François Grisez
Browse files
Add code in wrappers generator for reference handling in docstrings
parent
5e077c08
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
171 additions
and
28 deletions
+171
-28
tools/abstractapi.py
tools/abstractapi.py
+37
-1
tools/genapixml.py
tools/genapixml.py
+8
-7
tools/metadoc.py
tools/metadoc.py
+126
-20
No files found.
tools/abstractapi.py
View file @
2a3a2356
...
...
@@ -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
):
...
...
tools/genapixml.py
View file @
2a3a2356
...
...
@@ -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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
ev
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
e
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
sm
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
s
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
f
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
td
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
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
.
D
escription
(
node
.
find
(
'./briefdescription'
))
f
.
briefDoc
=
self
.
docparser
.
parse_d
escription
(
node
.
find
(
'./briefdescription'
))
f
.
detailedDescription
=
self
.
__cleanDescription
(
node
.
find
(
'./detaileddescription'
))
if
f
.
briefDescription
==
''
and
''
.
join
(
f
.
detailedDescription
.
itertext
()).
strip
()
==
''
:
return
None
...
...
tools/metadoc.py
View file @
2a3a2356
...
...
@@ -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
.
par
ts
))
lines
.
append
(
self
.
_translate_paragraph
(
par
a
))
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
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment