mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, properly look up names in all parent scopes.
See sphinx-doc/sphinx#1746.
This commit is contained in:
parent
c6865fd3ae
commit
0dc265ff01
@ -653,6 +653,7 @@ class ASTNestedNameElement(ASTBase):
|
|||||||
|
|
||||||
class ASTNestedName(ASTBase):
|
class ASTNestedName(ASTBase):
|
||||||
def __init__(self, names):
|
def __init__(self, names):
|
||||||
|
assert len(names) > 0
|
||||||
self.names = names
|
self.names = names
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -2392,6 +2393,7 @@ class CPPObject(ObjectDescription):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def add_target_and_index(self, ast, sig, signode):
|
def add_target_and_index(self, ast, sig, signode):
|
||||||
|
# general note: name must be lstrip(':')'ed, to remove "::"
|
||||||
try:
|
try:
|
||||||
id_v1 = ast.get_id_v1()
|
id_v1 = ast.get_id_v1()
|
||||||
except NoOldIdError:
|
except NoOldIdError:
|
||||||
@ -2403,7 +2405,7 @@ class CPPObject(ObjectDescription):
|
|||||||
theid = ids[0]
|
theid = ids[0]
|
||||||
ast.newestId = theid
|
ast.newestId = theid
|
||||||
assert theid # shouldn't be None
|
assert theid # shouldn't be None
|
||||||
name = text_type(ast.prefixedName)
|
name = text_type(ast.prefixedName).lstrip(':')
|
||||||
if theid not in self.state.document.ids:
|
if theid not in self.state.document.ids:
|
||||||
# if the name is not unique, the first one will win
|
# if the name is not unique, the first one will win
|
||||||
objects = self.env.domaindata['cpp']['objects']
|
objects = self.env.domaindata['cpp']['objects']
|
||||||
@ -2425,7 +2427,7 @@ class CPPObject(ObjectDescription):
|
|||||||
# then add the name to the parent scope
|
# then add the name to the parent scope
|
||||||
assert len(ast.prefixedName.names) > 0
|
assert len(ast.prefixedName.names) > 0
|
||||||
parentPrefixedAstName = ASTNestedName(ast.prefixedName.names[:-1])
|
parentPrefixedAstName = ASTNestedName(ast.prefixedName.names[:-1])
|
||||||
parentPrefixedName = text_type(parentPrefixedAstName)
|
parentPrefixedName = text_type(parentPrefixedAstName).lstrip(':')
|
||||||
if parentPrefixedName in objects:
|
if parentPrefixedName in objects:
|
||||||
docname, parentAst = objects[parentPrefixedName]
|
docname, parentAst = objects[parentPrefixedName]
|
||||||
if parentAst.objectType == 'enum' and not parentAst.scoped:
|
if parentAst.objectType == 'enum' and not parentAst.scoped:
|
||||||
@ -2433,12 +2435,12 @@ class CPPObject(ObjectDescription):
|
|||||||
assert len(parentAst.prefixedName.names) > 0
|
assert len(parentAst.prefixedName.names) > 0
|
||||||
enumScope = ASTNestedName(parentAst.prefixedName.names[:-1])
|
enumScope = ASTNestedName(parentAst.prefixedName.names[:-1])
|
||||||
unscopedName = enumeratorName.prefix_nested_name(enumScope)
|
unscopedName = enumeratorName.prefix_nested_name(enumScope)
|
||||||
txtUnscopedName = text_type(unscopedName)
|
txtUnscopedName = text_type(unscopedName).lstrip(':')
|
||||||
if not txtUnscopedName in objects:
|
if not txtUnscopedName in objects:
|
||||||
objects.setdefault(txtUnscopedName,
|
objects.setdefault(txtUnscopedName,
|
||||||
(self.env.docname, ast))
|
(self.env.docname, ast))
|
||||||
# add the uninstantiated template if it doesn't exist
|
# add the uninstantiated template if it doesn't exist
|
||||||
uninstantiated = ast.prefixedName.get_name_no_last_template()
|
uninstantiated = ast.prefixedName.get_name_no_last_template().lstrip(':')
|
||||||
if uninstantiated != name and uninstantiated not in objects:
|
if uninstantiated != name and uninstantiated not in objects:
|
||||||
signode['names'].append(uninstantiated)
|
signode['names'].append(uninstantiated)
|
||||||
objects.setdefault(uninstantiated, (self.env.docname, ast))
|
objects.setdefault(uninstantiated, (self.env.docname, ast))
|
||||||
@ -2694,7 +2696,7 @@ class CPPDomain(Domain):
|
|||||||
def _resolve_xref_inner(self, env, fromdocname, builder,
|
def _resolve_xref_inner(self, env, fromdocname, builder,
|
||||||
target, node, contnode, warn=True):
|
target, node, contnode, warn=True):
|
||||||
def _create_refnode(nameAst):
|
def _create_refnode(nameAst):
|
||||||
name = text_type(nameAst)
|
name = text_type(nameAst).lstrip(':')
|
||||||
if name not in self.data['objects']:
|
if name not in self.data['objects']:
|
||||||
# try dropping the last template
|
# try dropping the last template
|
||||||
name = nameAst.get_name_no_last_template()
|
name = nameAst.get_name_no_last_template()
|
||||||
@ -2714,18 +2716,25 @@ class CPPDomain(Domain):
|
|||||||
if warn:
|
if warn:
|
||||||
env.warn_node('unparseable C++ definition: %r' % target, node)
|
env.warn_node('unparseable C++ definition: %r' % target, node)
|
||||||
return None, None
|
return None, None
|
||||||
|
# If a name starts with ::, then it is global scope, so if
|
||||||
# try as is the name is fully qualified
|
# parent[0] = A::B
|
||||||
res = _create_refnode(nameAst)
|
# parent[1] = ::C
|
||||||
if res[0]:
|
# then we should look up in ::C, and in ::
|
||||||
return res
|
# Therefore, use only the last name as the basis of lookup.
|
||||||
|
|
||||||
# try qualifying it with the parent
|
|
||||||
parent = node.get('cpp:parent', None)
|
parent = node.get('cpp:parent', None)
|
||||||
if parent and len(parent) > 0:
|
if parent and len(parent) > 0:
|
||||||
return _create_refnode(nameAst.prefix_nested_name(parent[-1]))
|
parentScope = parent[-1].clone()
|
||||||
else:
|
else:
|
||||||
return None, None
|
#env.warn_node("C++ xref has no 'parent' set: %s" % target, node)
|
||||||
|
parentScope = ASTNestedName([ASTNestedNameElementEmpty()])
|
||||||
|
while len(parentScope.names) > 0:
|
||||||
|
name = nameAst.prefix_nested_name(parentScope)
|
||||||
|
res = _create_refnode(name)
|
||||||
|
if res[0]:
|
||||||
|
return res
|
||||||
|
parentScope.names.pop()
|
||||||
|
# finally try in global scope (we might have done that already though)
|
||||||
|
return _create_refnode(nameAst)
|
||||||
|
|
||||||
def resolve_xref(self, env, fromdocname, builder,
|
def resolve_xref(self, env, fromdocname, builder,
|
||||||
typ, target, node, contnode):
|
typ, target, node, contnode):
|
||||||
|
Loading…
Reference in New Issue
Block a user