mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, make lookup key point to correct overloads
This commit is contained in:
parent
703303139c
commit
80e08fe8fa
2
CHANGES
2
CHANGES
@ -43,6 +43,8 @@ Features added
|
|||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* C++, fix cross reference lookup in certain cases involving function overloads.
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -367,6 +367,8 @@ _keywords = [
|
|||||||
|
|
||||||
_max_id = 4
|
_max_id = 4
|
||||||
_id_prefix = [None, '', '_CPPv2', '_CPPv3', '_CPPv4']
|
_id_prefix = [None, '', '_CPPv2', '_CPPv3', '_CPPv4']
|
||||||
|
# Ids are used in lookup keys which are used across pickled files,
|
||||||
|
# so when _max_id changes, make sure to update the ENV_VERSION.
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Id v1 constants
|
# Id v1 constants
|
||||||
@ -1790,7 +1792,8 @@ class ASTTemplateIntroduction(ASTBase):
|
|||||||
|
|
||||||
|
|
||||||
class ASTTemplateDeclarationPrefix(ASTBase):
|
class ASTTemplateDeclarationPrefix(ASTBase):
|
||||||
def __init__(self, templates: List[Any]) -> None:
|
def __init__(self, templates: List[Union[ASTTemplateParams, ASTTemplateIntroduction]])\
|
||||||
|
-> None:
|
||||||
# templates is None means it's an explicit instantiation of a variable
|
# templates is None means it's an explicit instantiation of a variable
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
|
|
||||||
@ -3547,6 +3550,14 @@ class SymbolLookupResult:
|
|||||||
self.templateArgs = templateArgs
|
self.templateArgs = templateArgs
|
||||||
|
|
||||||
|
|
||||||
|
class LookupKey:
|
||||||
|
def __init__(self, data: List[Tuple[ASTNestedNameElement,
|
||||||
|
Union[ASTTemplateParams,
|
||||||
|
ASTTemplateIntroduction],
|
||||||
|
str]]) -> None:
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
class Symbol:
|
class Symbol:
|
||||||
debug_lookup = False
|
debug_lookup = False
|
||||||
debug_show_tree = False
|
debug_show_tree = False
|
||||||
@ -3570,8 +3581,8 @@ class Symbol:
|
|||||||
return super().__setattr__(key, value)
|
return super().__setattr__(key, value)
|
||||||
|
|
||||||
def __init__(self, parent: "Symbol", identOrOp: Union[ASTIdentifier, ASTOperator],
|
def __init__(self, parent: "Symbol", identOrOp: Union[ASTIdentifier, ASTOperator],
|
||||||
templateParams: Any, templateArgs: Any, declaration: ASTDeclaration,
|
templateParams: Union[ASTTemplateParams, ASTTemplateIntroduction],
|
||||||
docname: str) -> None:
|
templateArgs: Any, declaration: ASTDeclaration, docname: str) -> None:
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.identOrOp = identOrOp
|
self.identOrOp = identOrOp
|
||||||
self.templateParams = templateParams # template<templateParams>
|
self.templateParams = templateParams # template<templateParams>
|
||||||
@ -3669,7 +3680,11 @@ class Symbol:
|
|||||||
|
|
||||||
yield from c.children_recurse_anon
|
yield from c.children_recurse_anon
|
||||||
|
|
||||||
def get_lookup_key(self) -> List[Tuple[ASTNestedNameElement, Any]]:
|
def get_lookup_key(self)-> "LookupKey":
|
||||||
|
# The pickle files for the environment and for each document are distinct.
|
||||||
|
# The environment has all the symbols, but the documents has xrefs that
|
||||||
|
# must know their scope. A lookup key is essentially a specification of
|
||||||
|
# how to find a specific symbol.
|
||||||
symbols = []
|
symbols = []
|
||||||
s = self
|
s = self
|
||||||
while s.parent:
|
while s.parent:
|
||||||
@ -3679,14 +3694,23 @@ class Symbol:
|
|||||||
key = []
|
key = []
|
||||||
for s in symbols:
|
for s in symbols:
|
||||||
nne = ASTNestedNameElement(s.identOrOp, s.templateArgs)
|
nne = ASTNestedNameElement(s.identOrOp, s.templateArgs)
|
||||||
key.append((nne, s.templateParams))
|
if s.declaration is not None:
|
||||||
return key
|
key.append((nne, s.templateParams, s.declaration.get_newest_id()))
|
||||||
|
else:
|
||||||
|
key.append((nne, s.templateParams, None))
|
||||||
|
return LookupKey(key)
|
||||||
|
|
||||||
def get_full_nested_name(self) -> ASTNestedName:
|
def get_full_nested_name(self) -> ASTNestedName:
|
||||||
|
symbols = []
|
||||||
|
s = self
|
||||||
|
while s.parent:
|
||||||
|
symbols.append(s)
|
||||||
|
s = s.parent
|
||||||
|
symbols.reverse()
|
||||||
names = []
|
names = []
|
||||||
templates = []
|
templates = []
|
||||||
for nne, templateParams in self.get_lookup_key():
|
for s in symbols:
|
||||||
names.append(nne)
|
names.append(ASTNestedNameElement(s.identOrOp, s.templateArgs))
|
||||||
templates.append(False)
|
templates.append(False)
|
||||||
return ASTNestedName(names, templates, rooted=False)
|
return ASTNestedName(names, templates, rooted=False)
|
||||||
|
|
||||||
@ -4082,7 +4106,17 @@ class Symbol:
|
|||||||
|
|
||||||
def direct_lookup(self, key: List[Tuple[ASTNestedNameElement, Any]]) -> "Symbol":
|
def direct_lookup(self, key: List[Tuple[ASTNestedNameElement, Any]]) -> "Symbol":
|
||||||
s = self
|
s = self
|
||||||
for name, templateParams in key:
|
for name, templateParams, id_ in key.data:
|
||||||
|
if id_ is not None:
|
||||||
|
res = None
|
||||||
|
for cand in s._children:
|
||||||
|
if cand.declaration is None:
|
||||||
|
continue
|
||||||
|
if cand.declaration.get_newest_id() == id_:
|
||||||
|
res = cand
|
||||||
|
break
|
||||||
|
s = res
|
||||||
|
else:
|
||||||
identOrOp = name.identOrOp
|
identOrOp = name.identOrOp
|
||||||
templateArgs = name.templateArgs
|
templateArgs = name.templateArgs
|
||||||
s = s._find_first_named_symbol(identOrOp,
|
s = s._find_first_named_symbol(identOrOp,
|
||||||
@ -4091,7 +4125,7 @@ class Symbol:
|
|||||||
matchSelf=False,
|
matchSelf=False,
|
||||||
recurseInAnon=False,
|
recurseInAnon=False,
|
||||||
correctPrimaryTemplateArgs=False)
|
correctPrimaryTemplateArgs=False)
|
||||||
if not s:
|
if s is None:
|
||||||
return None
|
return None
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@ -5931,14 +5965,15 @@ class DefinitionParser:
|
|||||||
|
|
||||||
def _parse_template_declaration_prefix(self, objectType: str
|
def _parse_template_declaration_prefix(self, objectType: str
|
||||||
) -> ASTTemplateDeclarationPrefix:
|
) -> ASTTemplateDeclarationPrefix:
|
||||||
templates = [] # type: List[str]
|
templates = [] # type: List[Union[ASTTemplateParams, ASTTemplateIntroduction]]
|
||||||
while 1:
|
while 1:
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
# the saved position is only used to provide a better error message
|
# the saved position is only used to provide a better error message
|
||||||
|
params = None # type: Union[ASTTemplateParams, ASTTemplateIntroduction]
|
||||||
pos = self.pos
|
pos = self.pos
|
||||||
if self.skip_word("template"):
|
if self.skip_word("template"):
|
||||||
try:
|
try:
|
||||||
params = self._parse_template_parameter_list() # type: Any
|
params = self._parse_template_parameter_list()
|
||||||
except DefinitionError as e:
|
except DefinitionError as e:
|
||||||
if objectType == 'member' and len(templates) == 0:
|
if objectType == 'member' and len(templates) == 0:
|
||||||
return ASTTemplateDeclarationPrefix(None)
|
return ASTTemplateDeclarationPrefix(None)
|
||||||
@ -5990,7 +6025,7 @@ class DefinitionParser:
|
|||||||
msg += str(nestedName)
|
msg += str(nestedName)
|
||||||
self.warn(msg)
|
self.warn(msg)
|
||||||
|
|
||||||
newTemplates = []
|
newTemplates = [] # type: List[Union[ASTTemplateParams, ASTTemplateIntroduction]]
|
||||||
for i in range(numExtra):
|
for i in range(numExtra):
|
||||||
newTemplates.append(ASTTemplateParams([]))
|
newTemplates.append(ASTTemplateParams([]))
|
||||||
if templatePrefix and not isMemberInstantiation:
|
if templatePrefix and not isMemberInstantiation:
|
||||||
@ -6329,10 +6364,10 @@ class CPPObject(ObjectDescription):
|
|||||||
return ast
|
return ast
|
||||||
|
|
||||||
def before_content(self) -> None:
|
def before_content(self) -> None:
|
||||||
lastSymbol = self.env.temp_data['cpp:last_symbol']
|
lastSymbol = self.env.temp_data['cpp:last_symbol'] # type: Symbol
|
||||||
assert lastSymbol
|
assert lastSymbol
|
||||||
self.oldParentSymbol = self.env.temp_data['cpp:parent_symbol']
|
self.oldParentSymbol = self.env.temp_data['cpp:parent_symbol']
|
||||||
self.oldParentKey = self.env.ref_context['cpp:parent_key']
|
self.oldParentKey = self.env.ref_context['cpp:parent_key'] # type: LookupKey
|
||||||
self.env.temp_data['cpp:parent_symbol'] = lastSymbol
|
self.env.temp_data['cpp:parent_symbol'] = lastSymbol
|
||||||
self.env.ref_context['cpp:parent_key'] = lastSymbol.get_lookup_key()
|
self.env.ref_context['cpp:parent_key'] = lastSymbol.get_lookup_key()
|
||||||
|
|
||||||
@ -6824,13 +6859,13 @@ class CPPDomain(Domain):
|
|||||||
t, ex = findWarning(e)
|
t, ex = findWarning(e)
|
||||||
warner.warn('Unparseable C++ cross-reference: %r\n%s' % (t, ex))
|
warner.warn('Unparseable C++ cross-reference: %r\n%s' % (t, ex))
|
||||||
return None, None
|
return None, None
|
||||||
parentKey = node.get("cpp:parent_key", None)
|
parentKey = node.get("cpp:parent_key", None) # type: LookupKey
|
||||||
rootSymbol = self.data['root_symbol']
|
rootSymbol = self.data['root_symbol']
|
||||||
if parentKey:
|
if parentKey:
|
||||||
parentSymbol = rootSymbol.direct_lookup(parentKey)
|
parentSymbol = rootSymbol.direct_lookup(parentKey) # type: Symbol
|
||||||
if not parentSymbol:
|
if not parentSymbol:
|
||||||
print("Target: ", target)
|
print("Target: ", target)
|
||||||
print("ParentKey: ", parentKey)
|
print("ParentKey: ", parentKey.data)
|
||||||
print(rootSymbol.dump(1))
|
print(rootSymbol.dump(1))
|
||||||
assert parentSymbol # should be there
|
assert parentSymbol # should be there
|
||||||
else:
|
else:
|
||||||
@ -6977,8 +7012,8 @@ class CPPDomain(Domain):
|
|||||||
target = node.get('reftarget', None)
|
target = node.get('reftarget', None)
|
||||||
if target is None:
|
if target is None:
|
||||||
return None
|
return None
|
||||||
parentKey = node.get("cpp:parent_key", None)
|
parentKey = node.get("cpp:parent_key", None) # type: LookupKey
|
||||||
if parentKey is None or len(parentKey) <= 0:
|
if parentKey is None or len(parentKey.data) <= 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
rootSymbol = self.data['root_symbol']
|
rootSymbol = self.data['root_symbol']
|
||||||
|
@ -61,7 +61,7 @@ default_settings = {
|
|||||||
|
|
||||||
# This is increased every time an environment attribute is added
|
# This is increased every time an environment attribute is added
|
||||||
# or changed to properly invalidate pickle files.
|
# or changed to properly invalidate pickle files.
|
||||||
ENV_VERSION = 56
|
ENV_VERSION = 57
|
||||||
|
|
||||||
# config status
|
# config status
|
||||||
CONFIG_OK = 1
|
CONFIG_OK = 1
|
||||||
|
8
tests/roots/test-domain-cpp/lookup-key-overload.rst
Normal file
8
tests/roots/test-domain-cpp/lookup-key-overload.rst
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.. default-domain:: cpp
|
||||||
|
|
||||||
|
.. namespace:: lookup_key_overload
|
||||||
|
|
||||||
|
.. function:: void g(int a)
|
||||||
|
.. function:: void g(double b)
|
||||||
|
|
||||||
|
:var:`b`
|
@ -796,6 +796,13 @@ def filter_warnings(warning, file):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(testroot='domain-cpp')
|
||||||
|
def test_build_domain_cpp_multi_decl_lookup(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
ws = filter_warnings(warning, "lookup-key-overload")
|
||||||
|
assert len(ws) == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx(testroot='domain-cpp')
|
@pytest.mark.sphinx(testroot='domain-cpp')
|
||||||
def test_build_domain_cpp_misuse_of_roles(app, status, warning):
|
def test_build_domain_cpp_misuse_of_roles(app, status, warning):
|
||||||
app.builder.build_all()
|
app.builder.build_all()
|
||||||
|
Loading…
Reference in New Issue
Block a user