build(gen_vimdoc): eliminate non-constant global variables (#17781)

This commit is contained in:
dundargoc 2022-05-15 11:23:56 +02:00 committed by GitHub
parent 0a66c4a72a
commit b1b5802009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -79,13 +79,11 @@ LOG_LEVELS = {
] ]
} }
fmt_vimhelp = False # HACK
text_width = 78 text_width = 78
script_path = os.path.abspath(__file__) script_path = os.path.abspath(__file__)
base_dir = os.path.dirname(os.path.dirname(script_path)) base_dir = os.path.dirname(os.path.dirname(script_path))
out_dir = os.path.join(base_dir, 'tmp-{target}-doc') out_dir = os.path.join(base_dir, 'tmp-{target}-doc')
filter_cmd = '%s %s' % (sys.executable, script_path) filter_cmd = '%s %s' % (sys.executable, script_path)
seen_funcs = set()
msgs = [] # Messages to show on exit. msgs = [] # Messages to show on exit.
lua2dox_filter = os.path.join(base_dir, 'scripts', 'lua2dox_filter') lua2dox_filter = os.path.join(base_dir, 'scripts', 'lua2dox_filter')
@ -287,11 +285,6 @@ annotation_map = {
} }
# Tracks `xrefsect` titles. As of this writing, used only for separating
# deprecated functions.
xrefs = set()
# Raises an error with details about `o`, if `cond` is in object `o`, # Raises an error with details about `o`, if `cond` is in object `o`,
# or if `cond()` is callable and returns True. # or if `cond()` is callable and returns True.
def debug_this(o, cond=True): def debug_this(o, cond=True):
@ -485,10 +478,8 @@ def update_params_map(parent, ret_map, width=62):
return ret_map return ret_map
def render_node(n, text, prefix='', indent='', width=62): def render_node(n, text, prefix='', indent='', width=62, fmt_vimhelp=False):
"""Renders a node as Vim help text, recursively traversing all descendants.""" """Renders a node as Vim help text, recursively traversing all descendants."""
global fmt_vimhelp
global has_seen_preformatted
def ind(s): def ind(s):
return s if fmt_vimhelp else '' return s if fmt_vimhelp else ''
@ -566,7 +557,7 @@ def render_node(n, text, prefix='', indent='', width=62):
return text return text
def para_as_map(parent, indent='', width=62): def para_as_map(parent, indent='', width=62, fmt_vimhelp=False):
"""Extracts a Doxygen XML <para> node to a map. """Extracts a Doxygen XML <para> node to a map.
Keys: Keys:
@ -599,7 +590,8 @@ def para_as_map(parent, indent='', width=62):
last = '' last = ''
if is_inline(parent): if is_inline(parent):
# Flatten inline text from a tree of non-block nodes. # Flatten inline text from a tree of non-block nodes.
text = doc_wrap(render_node(parent, ""), indent=indent, width=width) text = doc_wrap(render_node(parent, "", fmt_vimhelp=fmt_vimhelp),
indent=indent, width=width)
else: else:
prev = None # Previous node prev = None # Previous node
for child in parent.childNodes: for child in parent.childNodes:
@ -615,7 +607,8 @@ def para_as_map(parent, indent='', width=62):
elif kind == 'see': elif kind == 'see':
groups['seealso'].append(child) groups['seealso'].append(child)
elif kind in ('note', 'warning'): elif kind in ('note', 'warning'):
text += render_node(child, text, indent=indent, width=width) text += render_node(child, text, indent=indent,
width=width, fmt_vimhelp=fmt_vimhelp)
else: else:
raise RuntimeError('unhandled simplesect: {}\n{}'.format( raise RuntimeError('unhandled simplesect: {}\n{}'.format(
child.nodeName, child.toprettyxml(indent=' ', newl='\n'))) child.nodeName, child.toprettyxml(indent=' ', newl='\n')))
@ -628,7 +621,8 @@ def para_as_map(parent, indent='', width=62):
and ' ' != text[-1]): and ' ' != text[-1]):
text += ' ' text += ' '
text += render_node(child, text, indent=indent, width=width) text += render_node(child, text, indent=indent, width=width,
fmt_vimhelp=fmt_vimhelp)
prev = child prev = child
chunks['text'] += text chunks['text'] += text
@ -639,10 +633,12 @@ def para_as_map(parent, indent='', width=62):
update_params_map(child, ret_map=chunks['params'], width=width) update_params_map(child, ret_map=chunks['params'], width=width)
for child in groups['return']: for child in groups['return']:
chunks['return'].append(render_node( chunks['return'].append(render_node(
child, '', indent=indent, width=width)) child, '', indent=indent, width=width, fmt_vimhelp=fmt_vimhelp))
for child in groups['seealso']: for child in groups['seealso']:
chunks['seealso'].append(render_node( chunks['seealso'].append(render_node(
child, '', indent=indent, width=width)) child, '', indent=indent, width=width, fmt_vimhelp=fmt_vimhelp))
xrefs = set()
for child in groups['xrefs']: for child in groups['xrefs']:
# XXX: Add a space (or any char) to `title` here, otherwise xrefs # XXX: Add a space (or any char) to `title` here, otherwise xrefs
# ("Deprecated" section) acts very weird... # ("Deprecated" section) acts very weird...
@ -652,10 +648,10 @@ def para_as_map(parent, indent='', width=62):
chunks['xrefs'].append(doc_wrap(xrefdesc, prefix='{}: '.format(title), chunks['xrefs'].append(doc_wrap(xrefdesc, prefix='{}: '.format(title),
width=width) + '\n') width=width) + '\n')
return chunks return chunks, xrefs
def fmt_node_as_vimhelp(parent, width=62, indent=''): def fmt_node_as_vimhelp(parent, width=62, indent='', fmt_vimhelp=False):
"""Renders (nested) Doxygen <para> nodes as Vim :help text. """Renders (nested) Doxygen <para> nodes as Vim :help text.
NB: Blank lines in a docstring manifest as <para> tags. NB: Blank lines in a docstring manifest as <para> tags.
@ -678,7 +674,7 @@ def fmt_node_as_vimhelp(parent, width=62, indent=''):
return True return True
for child in parent.childNodes: for child in parent.childNodes:
para = para_as_map(child, indent, width) para, _ = para_as_map(child, indent, width, fmt_vimhelp)
# Generate text from the gathered items. # Generate text from the gathered items.
chunks = [para['text']] chunks = [para['text']]
@ -702,19 +698,16 @@ def fmt_node_as_vimhelp(parent, width=62, indent=''):
return clean_lines('\n'.join(rendered_blocks).strip()) return clean_lines('\n'.join(rendered_blocks).strip())
def extract_from_xml(filename, target, width): def extract_from_xml(filename, target, width, fmt_vimhelp):
"""Extracts Doxygen info as maps without formatting the text. """Extracts Doxygen info as maps without formatting the text.
Returns two maps: Returns two maps:
1. Functions 1. Functions
2. Deprecated functions 2. Deprecated functions
The `fmt_vimhelp` global controls some special cases for use by The `fmt_vimhelp` variable controls some special cases for use by
fmt_doxygen_xml_as_vimhelp(). (TODO: ugly :) fmt_doxygen_xml_as_vimhelp(). (TODO: ugly :)
""" """
global xrefs
global fmt_vimhelp
xrefs.clear()
fns = {} # Map of func_name:docstring. fns = {} # Map of func_name:docstring.
deprecated_fns = {} # Map of func_name:docstring. deprecated_fns = {} # Map of func_name:docstring.
@ -821,16 +814,22 @@ def extract_from_xml(filename, target, width):
signature = prefix + suffix signature = prefix + suffix
signature += vimtag.rjust(width - len(signature)) signature += vimtag.rjust(width - len(signature))
# Tracks `xrefsect` titles. As of this writing, used only for separating
# deprecated functions.
xrefs_all = set()
paras = [] paras = []
brief_desc = find_first(member, 'briefdescription') brief_desc = find_first(member, 'briefdescription')
if brief_desc: if brief_desc:
for child in brief_desc.childNodes: for child in brief_desc.childNodes:
paras.append(para_as_map(child)) para, xrefs = para_as_map(child)
xrefs_all.update(xrefs)
desc = find_first(member, 'detaileddescription') desc = find_first(member, 'detaileddescription')
if desc: if desc:
for child in desc.childNodes: for child in desc.childNodes:
paras.append(para_as_map(child)) para, xrefs = para_as_map(child)
paras.append(para)
xrefs_all.update(xrefs)
log.debug( log.debug(
textwrap.indent( textwrap.indent(
re.sub(r'\n\s*\n+', '\n', re.sub(r'\n\s*\n+', '\n',
@ -846,7 +845,6 @@ def extract_from_xml(filename, target, width):
'seealso': [], 'seealso': [],
} }
if fmt_vimhelp: if fmt_vimhelp:
# HACK :(
fn['desc_node'] = desc fn['desc_node'] = desc
fn['brief_desc_node'] = brief_desc fn['brief_desc_node'] = brief_desc
@ -865,18 +863,16 @@ def extract_from_xml(filename, target, width):
if INCLUDE_C_DECL: if INCLUDE_C_DECL:
fn['c_decl'] = c_decl fn['c_decl'] = c_decl
if 'Deprecated' in str(xrefs): if 'Deprecated' in str(xrefs_all):
deprecated_fns[name] = fn deprecated_fns[name] = fn
elif name.startswith(CONFIG[target]['fn_name_prefix']): elif name.startswith(CONFIG[target]['fn_name_prefix']):
fns[name] = fn fns[name] = fn
xrefs.clear()
fns = collections.OrderedDict(sorted( fns = collections.OrderedDict(sorted(
fns.items(), fns.items(),
key=lambda key_item_tuple: key_item_tuple[0].lower())) key=lambda key_item_tuple: key_item_tuple[0].lower()))
deprecated_fns = collections.OrderedDict(sorted(deprecated_fns.items())) deprecated_fns = collections.OrderedDict(sorted(deprecated_fns.items()))
return (fns, deprecated_fns) return fns, deprecated_fns
def fmt_doxygen_xml_as_vimhelp(filename, target): def fmt_doxygen_xml_as_vimhelp(filename, target):
@ -886,16 +882,14 @@ def fmt_doxygen_xml_as_vimhelp(filename, target):
1. Vim help text for functions found in `filename`. 1. Vim help text for functions found in `filename`.
2. Vim help text for deprecated functions. 2. Vim help text for deprecated functions.
""" """
global fmt_vimhelp
fmt_vimhelp = True
fns_txt = {} # Map of func_name:vim-help-text. fns_txt = {} # Map of func_name:vim-help-text.
deprecated_fns_txt = {} # Map of func_name:vim-help-text. deprecated_fns_txt = {} # Map of func_name:vim-help-text.
fns, _ = extract_from_xml(filename, target, width=text_width) fns, _ = extract_from_xml(filename, target, text_width, True)
for name, fn in fns.items(): for name, fn in fns.items():
# Generate Vim :help for parameters. # Generate Vim :help for parameters.
if fn['desc_node']: if fn['desc_node']:
doc = fmt_node_as_vimhelp(fn['desc_node']) doc = fmt_node_as_vimhelp(fn['desc_node'], fmt_vimhelp=True)
if not doc and fn['brief_desc_node']: if not doc and fn['brief_desc_node']:
doc = fmt_node_as_vimhelp(fn['brief_desc_node']) doc = fmt_node_as_vimhelp(fn['brief_desc_node'])
if not doc: if not doc:
@ -948,14 +942,9 @@ def fmt_doxygen_xml_as_vimhelp(filename, target):
func_doc = "\n".join(split_lines) func_doc = "\n".join(split_lines)
if 'Deprecated' in xrefs: if name.startswith(CONFIG[target]['fn_name_prefix']):
deprecated_fns_txt[name] = func_doc
elif name.startswith(CONFIG[target]['fn_name_prefix']):
fns_txt[name] = func_doc fns_txt[name] = func_doc
xrefs.clear()
fmt_vimhelp = False
return ('\n\n'.join(list(fns_txt.values())), return ('\n\n'.join(list(fns_txt.values())),
'\n\n'.join(list(deprecated_fns_txt.values()))) '\n\n'.join(list(deprecated_fns_txt.values())))
@ -1059,7 +1048,7 @@ def main(config, args):
xmlfile = os.path.join(base, xmlfile = os.path.join(base,
'{}.xml'.format(compound.getAttribute('refid'))) '{}.xml'.format(compound.getAttribute('refid')))
# Extract unformatted (*.mpack). # Extract unformatted (*.mpack).
fn_map, _ = extract_from_xml(xmlfile, target, width=9999) fn_map, _ = extract_from_xml(xmlfile, target, 9999, False)
# Extract formatted (:help). # Extract formatted (:help).
functions_text, deprecated_text = fmt_doxygen_xml_as_vimhelp( functions_text, deprecated_text = fmt_doxygen_xml_as_vimhelp(
os.path.join(base, '{}.xml'.format( os.path.join(base, '{}.xml'.format(