summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Lykke Andersen <Jakob@caput.dk>2020-01-20 19:20:35 +0100
committerJakob Lykke Andersen <Jakob@caput.dk>2020-01-20 19:40:00 +0100
commit6d7ff482f6af6f3066e1c15d3dd8cae2ee554db8 (patch)
tree13e53b425013ac96a6f817d0683d67b2bf1c2bc5
parentc07c618f1b034dd40a25468da6b7954cc77b41de (diff)
downloadsphinx-git-6d7ff482f6af6f3066e1c15d3dd8cae2ee554db8.tar.gz
C++, test role target checks and fix two cases
-rw-r--r--CHANGES4
-rw-r--r--sphinx/domains/cpp.py11
-rw-r--r--tests/roots/test-domain-cpp/roles-targets-ok.rst170
-rw-r--r--tests/roots/test-domain-cpp/roles-targets-warn.rst158
-rw-r--r--tests/test_domain_cpp.py52
5 files changed, 391 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index 7e782410f..bef70360a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -16,6 +16,10 @@ Features added
Bugs fixed
----------
+* C++, don't crash when using the ``struct`` role in some cases.
+* C++, don't warn when using the ``var``/``member`` role for function
+ parameters.
+
Testing
--------
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 4928fb997..53722b124 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -7258,23 +7258,30 @@ class CPPDomain(Domain):
if typ.startswith('cpp:'):
typ = typ[4:]
+ origTyp = typ
if typ == 'func':
typ = 'function'
+ if typ == 'struct':
+ typ = 'class'
declTyp = s.declaration.objectType
def checkType():
if typ == 'any' or typ == 'identifier':
return True
if declTyp == 'templateParam':
+ # TODO: perhaps this should be strengthened one day
return True
+ if declTyp == 'functionParam':
+ if typ == 'var' or typ == 'member':
+ return True
objtypes = self.objtypes_for_role(typ)
if objtypes:
return declTyp in objtypes
- print("Type is %s, declType is %s" % (typ, declTyp))
+ print("Type is %s (originally: %s), declType is %s" % (typ, origTyp, declTyp))
assert False
if not checkType():
warner.warn("cpp:%s targets a %s (%s)."
- % (typ, s.declaration.objectType,
+ % (origTyp, s.declaration.objectType,
s.get_full_nested_name()))
declaration = s.declaration
diff --git a/tests/roots/test-domain-cpp/roles-targets-ok.rst b/tests/roots/test-domain-cpp/roles-targets-ok.rst
new file mode 100644
index 000000000..e70b9259f
--- /dev/null
+++ b/tests/roots/test-domain-cpp/roles-targets-ok.rst
@@ -0,0 +1,170 @@
+.. default-domain:: cpp
+
+.. namespace:: RolesTargetsOk
+
+.. class:: Class
+
+ :cpp:any:`Class`
+ :class:`Class`
+ :struct:`Class`
+ union
+ func
+ member
+ var
+ :type:`Class`
+ concept
+ enum
+ enumerator
+
+.. union:: Union
+
+ :cpp:any:`Union`
+ class
+ struct
+ :union:`Union`
+ func
+ member
+ var
+ :type:`Union`
+ concept
+ enum
+ enumerator
+
+.. function:: void Function()
+
+ :cpp:any:`Function`
+ class
+ struct
+ union
+ :func:`Function`
+ member
+ var
+ :type:`Function`
+ concept
+ enum
+ enumerator
+
+.. var:: int Variable
+
+ :cpp:any:`Variable`
+ class
+ struct
+ union
+ function
+ :member:`Variable`
+ :var:`Variables`
+ type
+ concept
+ enum
+ enumerator
+
+.. type:: Type = void
+
+ :cpp:any:`Type`
+ class
+ struct
+ union
+ function
+ member
+ var
+ :type:`Type`
+ concept
+ enum
+ enumerator
+
+.. concept:: template<typename T> Concept
+
+ :cpp:any:`Concept`
+ class
+ struct
+ union
+ function
+ member
+ var
+ type
+ :concept:`Concept`
+ enum
+ enumerator
+
+.. enum-struct:: Enum
+
+ :cpp:any:`Enum`
+ class
+ struct
+ union
+ function
+ member
+ var
+ :type:`Enum`
+ concept
+ :enum:`Enum`
+ enumerator
+
+ .. enumerator:: Enumerator
+
+ :cpp:any:`Enumerator`
+ class
+ struct
+ union
+ function
+ member
+ var
+ type
+ concept
+ enum
+ :enumerator:`Enumerator`
+
+.. class:: template<typename TParamType, \
+ int TParamVar, \
+ template<typename> typename TParamTemplate \
+ > ClassTemplate
+
+ :cpp:any:`TParamType`
+ :class:`TParamType`
+ :struct:`TParamType`
+ :union:`TParamType`
+ :func:`TParamType`
+ :member:`TParamType`
+ :var:`TParamType`
+ :type:`TParamType`
+ :concept:`TParamType`
+ :enum:`TParamType`
+ :enumerator:`TParamType`
+
+ :cpp:any:`TParamVar`
+ :class:`TParamVar`
+ :struct:`TParamVar`
+ :union:`TParamVar`
+ :func:`TParamVar`
+ :member:`TParamVar`
+ :var:`TParamVar`
+ :type:`TParamVar`
+ :concept:`TParamVar`
+ :enum:`TParamVar`
+ :enumerator:`TParamVar`
+
+ :cpp:any:`TParamTemplate`
+ :class:`TParamTemplate`
+ :struct:`TParamTemplate`
+ :union:`TParamTemplate`
+ :func:`TParamTemplate`
+ :member:`TParamTemplate`
+ :var:`TParamTemplate`
+ :type:`TParamTemplate`
+ :concept:`TParamTemplate`
+ :enum:`TParamTemplate`
+ :enumerator:`TParamTemplate`
+
+.. function:: void FunctionParams(int FunctionParam)
+
+ :cpp:any:`FunctionParam`
+ class
+ struct
+ union
+ function
+ :member:`FunctionParam`
+ :var:`FunctionParam`
+ type
+ concept
+ enum
+ enumerator
diff --git a/tests/roots/test-domain-cpp/roles-targets-warn.rst b/tests/roots/test-domain-cpp/roles-targets-warn.rst
new file mode 100644
index 000000000..decebe170
--- /dev/null
+++ b/tests/roots/test-domain-cpp/roles-targets-warn.rst
@@ -0,0 +1,158 @@
+.. default-domain:: cpp
+
+.. namespace:: RolesTargetsWarn
+
+.. class:: Class
+
+ class
+ struct
+ :union:`Class`
+ :func:`Class`
+ :member:`Class`
+ :var:`Class`
+ type
+ :concept:`Class`
+ :enum:`Class`
+ :enumerator:`Class`
+
+.. union:: Union
+
+ :class:`Union`
+ :struct:`Union`
+ union
+ :func:`Union`
+ :member:`Union`
+ :var:`Union`
+ type
+ :concept:`Union`
+ :enum:`Union`
+ :enumerator:`Union`
+
+.. function:: void Function()
+
+ :class:`Function`
+ :struct:`Function`
+ :union:`Function`
+ func
+ :member:`Function`
+ :var:`Function`
+ type
+ :concept:`Function`
+ :enum:`Function`
+ :enumerator:`Function`
+
+.. var:: int Variable
+
+ :class:`Variable`
+ :struct:`Variable`
+ :union:`Variable`
+ :func:`Variable`
+ member
+ var
+ :type:`Variable`
+ :concept:`Variable`
+ :enum:`Variable`
+ :enumerator:`Variable`
+
+.. type:: Type = void
+
+ :class:`Type`
+ :struct:`Type`
+ :union:`Type`
+ :func:`Type`
+ :member:`Type`
+ :var:`Type`
+ type
+ :concept:`Type`
+ :enum:`Type`
+ :enumerator:`Type`
+
+.. concept:: template<typename T> Concept
+
+ :class:`Concept`
+ :struct:`Concept`
+ :union:`Concept`
+ :func:`Concept`
+ :member:`Concept`
+ :var:`Concept`
+ :type:`Concept`
+ concept
+ :enum:`Concept`
+ :enumerator:`Concept`
+
+.. enum-struct:: Enum
+
+ :class:`Enum`
+ :struct:`Enum`
+ :union:`Enum`
+ :func:`Enum`
+ :member:`Enum`
+ :var:`Enum`
+ type
+ :concept:`Enum`
+ enum
+ :enumerator:`Enum`
+
+ .. enumerator:: Enumerator
+
+ :class:`Enumerator`
+ :struct:`Enumerator`
+ :union:`Enumerator`
+ :func:`Enumerator`
+ :member:`Enumerator`
+ :var:`Enumerator`
+ :type:`Enumerator`
+ :concept:`Enumerator`
+ :enum:`Enumerator`
+ enumerator
+
+.. class:: template<typename TParamType, \
+ int TParamVar, \
+ template<typename> typename TParamTemplate \
+ > ClassTemplate
+
+ class
+ struct
+ union
+ func
+ member
+ var
+ type
+ concept
+ enum
+ enumerator
+
+ class
+ struct
+ union
+ func
+ member
+ var
+ type
+ concept
+ enum
+ enumerator
+
+ class
+ struct
+ union
+ func
+ member
+ var
+ type
+ concept
+ enum
+ enumerator
+
+.. function:: void FunctionParams(int FunctionParam)
+
+ :class:`FunctionParam`
+ :struct:`FunctionParam`
+ :union:`FunctionParam`
+ :func:`FunctionParam`
+ member
+ var
+ :type:`FunctionParam`
+ :concept:`FunctionParam`
+ :enum:`FunctionParam`
+ :enumerator:`FunctionParam`
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index df1e1bae1..7626ff99d 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -786,11 +786,59 @@ def test_xref_parsing():
# raise DefinitionError("")
+def filter_warnings(warning, file):
+ lines = warning.getvalue().split("\n");
+ res = [l for l in lines if "/domain-cpp/{}.rst".format(file) in l and
+ "WARNING: document isn't included in any toctree" not in l]
+ print("Filtered warnings for file '{}':".format(file))
+ for w in res:
+ print(w)
+ return res
+
+
@pytest.mark.sphinx(testroot='domain-cpp')
def test_build_domain_cpp_misuse_of_roles(app, status, warning):
app.builder.build_all()
-
- # TODO: properly check for the warnings we expect
+ ws = filter_warnings(warning, "roles-targets-ok")
+ assert len(ws) == 0
+
+ ws = filter_warnings(warning, "roles-targets-warn")
+ # the roles that should be able to generate warnings:
+ allRoles = ['class', 'struct', 'union', 'func', 'member', 'var', 'type', 'concept', 'enum', 'enumerator']
+ ok = [ # targetType, okRoles
+ ('class', ['class', 'struct', 'type']),
+ ('union', ['union', 'type']),
+ ('func', ['func', 'type']),
+ ('member', ['member', 'var']),
+ ('type', ['type']),
+ ('concept', ['concept']),
+ ('enum', ['type', 'enum']),
+ ('enumerator', ['enumerator']),
+ ('tParam', ['class', 'struct', 'union', 'func', 'member', 'var', 'type', 'concept', 'enum', 'enumerator', 'functionParam']),
+ ('functionParam', ['member', 'var']),
+ ]
+ warn = []
+ for targetType, roles in ok:
+ txtTargetType = "function" if targetType == "func" else targetType
+ for r in allRoles:
+ if r not in roles:
+ warn.append("WARNING: cpp:{} targets a {} (".format(r, txtTargetType))
+ warn = list(sorted(warn))
+ for w in ws:
+ assert "targets a" in w
+ ws = [w[w.index("WARNING:"):] for w in ws]
+ ws = list(sorted(ws))
+ print("Expected warnings:")
+ for w in warn:
+ print(w)
+ print("Actual warnings:")
+ for w in ws:
+ print(w)
+
+ for i in range(min(len(warn), len(ws))):
+ assert ws[i].startswith(warn[i])
+
+ assert len(ws) == len(warn)
@pytest.mark.skipif(docutils.__version_info__ < (0, 13),