Skip to content

Commit

Permalink
Merge branch '3.2.x' into 3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Nov 1, 2020
2 parents 27b1a69 + 2118ff1 commit b415b25
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 77 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ Deprecated
Features added
--------------

- C and C++, show line numbers for previous declarations when duplicates are
detected.

Bugs fixed
----------

Expand Down
1 change: 1 addition & 0 deletions sphinx/builders/linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def check(docname: str) -> Tuple[str, str, int]:
if rex.match(uri):
return 'ignored', '', 0
else:
self.broken[uri] = ''
return 'broken', '', 0
elif uri in self.good:
return 'working', 'old', 0
Expand Down
75 changes: 42 additions & 33 deletions sphinx/domains/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ def __deepcopy__(self, memo):
assert False # shouldn't happen
else:
# the domain base class makes a copy of the initial data, which is fine
return Symbol(None, None, None, None)
return Symbol(None, None, None, None, None)

@staticmethod
def debug_print(*args: Any) -> None:
Expand All @@ -1498,14 +1498,15 @@ def __setattr__(self, key: str, value: Any) -> None:
return super().__setattr__(key, value)

def __init__(self, parent: "Symbol", ident: ASTIdentifier,
declaration: ASTDeclaration, docname: str) -> None:
declaration: ASTDeclaration, docname: str, line: int) -> None:
self.parent = parent
# declarations in a single directive are linked together
self.siblingAbove = None # type: Symbol
self.siblingBelow = None # type: Symbol
self.ident = ident
self.declaration = declaration
self.docname = docname
self.line = line
self.isRedeclaration = False
self._assert_invariants()

Expand All @@ -1521,12 +1522,14 @@ def __init__(self, parent: "Symbol", ident: ASTIdentifier,
# Do symbol addition after self._children has been initialised.
self._add_function_params()

def _fill_empty(self, declaration: ASTDeclaration, docname: str) -> None:
def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None:
self._assert_invariants()
assert not self.declaration
assert not self.docname
assert declaration
assert docname
assert self.declaration is None
assert self.docname is None
assert self.line is None
assert declaration is not None
assert docname is not None
assert line is not None
self.declaration = declaration
self.declaration.symbol = self
self.docname = docname
Expand All @@ -1553,7 +1556,7 @@ def _add_function_params(self) -> None:
decl = ASTDeclaration('functionParam', None, p)
assert not nn.rooted
assert len(nn.names) == 1
self._add_symbols(nn, decl, self.docname)
self._add_symbols(nn, decl, self.docname, self.line)
if Symbol.debug_lookup:
Symbol.debug_indent -= 1

Expand All @@ -1570,6 +1573,7 @@ def clear_doc(self, docname: str) -> None:
if sChild.declaration and sChild.docname == docname:
sChild.declaration = None
sChild.docname = None
sChild.line = None
if sChild.siblingAbove is not None:
sChild.siblingAbove.siblingBelow = sChild.siblingBelow
if sChild.siblingBelow is not None:
Expand Down Expand Up @@ -1763,7 +1767,7 @@ def _symbol_lookup(self, nestedName: ASTNestedName,
return SymbolLookupResult(symbols, parentSymbol, ident)

def _add_symbols(self, nestedName: ASTNestedName,
declaration: ASTDeclaration, docname: str) -> "Symbol":
declaration: ASTDeclaration, docname: str, line: int) -> "Symbol":
# TODO: further simplification from C++ to C
# Used for adding a whole path of symbols, where the last may or may not
# be an actual declaration.
Expand All @@ -1772,9 +1776,9 @@ def _add_symbols(self, nestedName: ASTNestedName,
Symbol.debug_indent += 1
Symbol.debug_print("_add_symbols:")
Symbol.debug_indent += 1
Symbol.debug_print("nn: ", nestedName)
Symbol.debug_print("decl: ", declaration)
Symbol.debug_print("doc: ", docname)
Symbol.debug_print("nn: ", nestedName)
Symbol.debug_print("decl: ", declaration)
Symbol.debug_print("location: {}:{}".format(docname, line))

def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "Symbol":
if Symbol.debug_lookup:
Expand All @@ -1784,7 +1788,7 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "S
Symbol.debug_print("ident: ", ident)
Symbol.debug_indent -= 2
return Symbol(parent=parentSymbol, ident=ident,
declaration=None, docname=None)
declaration=None, docname=None, line=None)

lookupResult = self._symbol_lookup(nestedName,
onMissingQualifiedSymbol,
Expand All @@ -1800,12 +1804,12 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "S
Symbol.debug_indent += 1
Symbol.debug_print("ident: ", lookupResult.ident)
Symbol.debug_print("declaration: ", declaration)
Symbol.debug_print("docname: ", docname)
Symbol.debug_print("location: {}:{}".format(docname, line))
Symbol.debug_indent -= 1
symbol = Symbol(parent=lookupResult.parentSymbol,
ident=lookupResult.ident,
declaration=declaration,
docname=docname)
docname=docname, line=line)
if Symbol.debug_lookup:
Symbol.debug_indent -= 2
return symbol
Expand Down Expand Up @@ -1853,7 +1857,7 @@ def makeCandSymbol() -> "Symbol":
symbol = Symbol(parent=lookupResult.parentSymbol,
ident=lookupResult.ident,
declaration=declaration,
docname=docname)
docname=docname, line=line)
if Symbol.debug_lookup:
Symbol.debug_print("end: creating candidate symbol")
return symbol
Expand Down Expand Up @@ -1919,7 +1923,7 @@ def handleDuplicateDeclaration(symbol: "Symbol", candSymbol: "Symbol") -> None:
# .. namespace:: Test
# .. namespace:: nullptr
# .. class:: Test
symbol._fill_empty(declaration, docname)
symbol._fill_empty(declaration, docname, line)
return symbol

def merge_with(self, other: "Symbol", docnames: List[str],
Expand All @@ -1940,13 +1944,15 @@ def merge_with(self, other: "Symbol", docnames: List[str],
continue
if otherChild.declaration and otherChild.docname in docnames:
if not ourChild.declaration:
ourChild._fill_empty(otherChild.declaration, otherChild.docname)
ourChild._fill_empty(otherChild.declaration,
otherChild.docname, otherChild.line)
elif ourChild.docname != otherChild.docname:
name = str(ourChild.declaration)
msg = __("Duplicate C declaration, also defined in '%s'.\n"
"Declaration is '%s'.")
msg = msg % (ourChild.docname, name)
logger.warning(msg, location=otherChild.docname)
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
"Declaration is '.. c:%s:: %s'.")
msg = msg % (ourChild.docname, ourChild.line,
ourChild.declaration.directiveType, name)
logger.warning(msg, location=(otherChild.docname, otherChild.line))
else:
# Both have declarations, and in the same docname.
# This can apparently happen, it should be safe to
Expand All @@ -1960,19 +1966,21 @@ def add_name(self, nestedName: ASTNestedName) -> "Symbol":
if Symbol.debug_lookup:
Symbol.debug_indent += 1
Symbol.debug_print("add_name:")
res = self._add_symbols(nestedName, declaration=None, docname=None)
res = self._add_symbols(nestedName, declaration=None, docname=None, line=None)
if Symbol.debug_lookup:
Symbol.debug_indent -= 1
return res

def add_declaration(self, declaration: ASTDeclaration, docname: str) -> "Symbol":
def add_declaration(self, declaration: ASTDeclaration,
docname: str, line: int) -> "Symbol":
if Symbol.debug_lookup:
Symbol.debug_indent += 1
Symbol.debug_print("add_declaration:")
assert declaration
assert docname
assert declaration is not None
assert docname is not None
assert line is not None
nestedName = declaration.name
res = self._add_symbols(nestedName, declaration, docname)
res = self._add_symbols(nestedName, declaration, docname, line)
if Symbol.debug_lookup:
Symbol.debug_indent -= 1
return res
Expand Down Expand Up @@ -3149,7 +3157,7 @@ def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None:
declClone.enumeratorScopedSymbol = symbol
Symbol(parent=targetSymbol, ident=symbol.ident,
declaration=declClone,
docname=self.env.docname)
docname=self.env.docname, line=self.get_source_info()[1])

def add_target_and_index(self, ast: ASTDeclaration, sig: str,
signode: TextElement) -> None:
Expand Down Expand Up @@ -3252,7 +3260,8 @@ def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration:
raise ValueError from e

try:
symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
symbol = parentSymbol.add_declaration(
ast, docname=self.env.docname, line=self.get_source_info()[1])
# append the new declaration to the sibling list
assert symbol.siblingAbove is None
assert symbol.siblingBelow is None
Expand All @@ -3265,9 +3274,9 @@ def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration:
# Assume we are actually in the old symbol,
# instead of the newly created duplicate.
self.env.temp_data['c:last_symbol'] = e.symbol
msg = __("Duplicate C declaration, also defined in '%s'.\n"
"Declaration is '%s'.")
msg = msg % (e.symbol.docname, sig)
msg = __("Duplicate C declaration, also defined at %s:%s.\n"
"Declaration is '.. c:%s:: %s'.")
msg = msg % (e.symbol.docname, e.symbol.line, self.display_object_type, sig)
logger.warning(msg, location=signode)

if ast.objectType == 'enumerator':
Expand Down Expand Up @@ -3694,7 +3703,7 @@ class CDomain(Domain):
'texpr': CExprRole(asCode=False)
}
initial_data = {
'root_symbol': Symbol(None, None, None, None),
'root_symbol': Symbol(None, None, None, None, None),
'objects': {}, # fullname -> docname, node_id, objtype
} # type: Dict[str, Union[Symbol, Dict[str, Tuple[str, str, str]]]]

Expand Down
Loading

0 comments on commit b415b25

Please sign in to comment.