Skip to content

Commit fc29313

Browse files
committed
Add support for typedoc 0.23
1 parent 5438ce4 commit fc29313

File tree

6 files changed

+78
-16
lines changed

6 files changed

+78
-16
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
fail-fast: false
6262
matrix:
6363
python-version: ['3.10', '3.11']
64-
typedoc-version: ['0.20', '0.21', '0.22']
64+
typedoc-version: ['0.20', '0.21', '0.22', '0.23']
6565
experimental: [false]
6666

6767
name: Python ${{ matrix.python-version}} + typedoc ${{ matrix.typedoc-version }}

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def tests(session: Session) -> None:
1212

1313

1414
@nox.session(python=["3.10", "3.11"])
15-
@nox.parametrize("typedoc", ["0.20", "0.21", "0.22"])
15+
@nox.parametrize("typedoc", ["0.20", "0.21", "0.22", "0.23"])
1616
def test_typedoc(session: Session, typedoc: str) -> None:
1717

1818
session.install("-r", "requirements_dev.txt")

sphinx_js/typedoc.py

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,20 @@ def _populate_index_inner(
120120

121121
children.append(node.children)
122122
if isinstance(node, Accessor):
123-
children.append(node.getSignature)
124-
children.append(node.setSignature)
123+
if node.getSignature:
124+
if isinstance(node.getSignature, list):
125+
sig = node.getSignature[0]
126+
else:
127+
sig = node.getSignature
128+
node.getSignature = sig
129+
children.append([sig])
130+
if node.setSignature:
131+
if isinstance(node.setSignature, list):
132+
sig = node.setSignature[0]
133+
else:
134+
sig = node.setSignature
135+
node.setSignature = sig
136+
children.append([sig])
125137

126138
if isinstance(node, Callable):
127139
children.append(node.signatures)
@@ -132,6 +144,7 @@ def _populate_index_inner(
132144

133145
if isinstance(node, ClassOrInterface):
134146
children.append(node.typeParameter)
147+
children.append(node.typeParameters)
135148

136149
for child in (c for l in children for c in l):
137150
self._populate_index_inner(
@@ -253,10 +266,31 @@ class Source(BaseModel):
253266
line: int
254267

255268

269+
class Summary(BaseModel):
270+
kind: Literal["text"]
271+
text: str
272+
273+
274+
class Tag(BaseModel):
275+
tag: str
276+
content: list[Summary]
277+
278+
256279
class Comment(BaseModel):
257280
returns: str = ""
258281
shortText: str | None
259282
text: str | None
283+
summary: list[Summary] | None
284+
blockTags: list[Tag] = []
285+
286+
def get_returns(self) -> str:
287+
result = self.returns.strip()
288+
if result:
289+
return result
290+
for tag in self.blockTags:
291+
if tag.tag == "@returns":
292+
return tag.content[0].text.strip()
293+
return ""
260294

261295

262296
class Flags(BaseModel):
@@ -359,17 +393,17 @@ def _path_segments(self, base_dir: str) -> list[str]:
359393

360394
class Accessor(NodeBase):
361395
kindString: Literal["Accessor"]
362-
getSignature: list["Signature"] = []
363-
setSignature: list["Signature"] = []
396+
getSignature: "list[Signature] | Signature" = []
397+
setSignature: "list[Signature] | Signature" = []
364398

365399
def to_ir(self, converter: Converter) -> tuple[ir.Attribute, Sequence["Node"]]:
366400
if self.getSignature:
367401
# There's no signature to speak of for a getter: only a return type.
368-
type = self.getSignature[0].type
402+
type = self.getSignature.type # type: ignore[union-attr]
369403
else:
370404
# ES6 says setters have exactly 1 param. I'm not sure if they
371405
# can have multiple signatures, though.
372-
type = self.setSignature[0].parameters[0].type
406+
type = self.setSignature.parameters[0].type # type: ignore[union-attr]
373407
res = ir.Attribute(
374408
type=type.render_name(converter),
375409
**self.member_properties(),
@@ -410,6 +444,7 @@ class ClassOrInterface(NodeBase):
410444
implementedTypes: list["TypeD"] = []
411445
children: Sequence["ClassChild"] = []
412446
typeParameter: list["TypeParameter"] = []
447+
typeParameters: list["TypeParameter"] = []
413448

414449
def _related_types(
415450
self,
@@ -486,7 +521,9 @@ def to_ir(self, converter: Converter) -> tuple[ir.Class | None, Sequence["Node"]
486521
supers=self._related_types(converter, kind="extendedTypes"),
487522
is_abstract=self.flags.isAbstract,
488523
interfaces=self._related_types(converter, kind="implementedTypes"),
489-
type_params=[x.to_ir(converter) for x in self.typeParameter],
524+
type_params=[
525+
x.to_ir(converter) for x in self.typeParameter or self.typeParameters
526+
],
490527
**self._top_level_properties(),
491528
)
492529
return result, self.children
@@ -569,7 +606,10 @@ class OtherNode(NodeBase):
569606

570607
def make_description(comment: Comment) -> str:
571608
"""Construct a single comment string from a fancy object."""
572-
ret = "\n\n".join(text for text in [comment.shortText, comment.text] if text)
609+
if comment.summary:
610+
ret = comment.summary[0].text
611+
else:
612+
ret = "\n\n".join(text for text in [comment.shortText, comment.text] if text)
573613
return ret.strip()
574614

575615

@@ -625,6 +665,7 @@ class Signature(TopLevelProperties):
625665

626666
name: str
627667
typeParameter: list[TypeParameter] = []
668+
typeParameters: list[TypeParameter] = []
628669
parameters: list["Param"] = []
629670
sources: list[Source] = []
630671
type: "TypeD" # This is the return type!
@@ -644,10 +685,11 @@ def return_type(self, converter: Converter) -> list[ir.Return]:
644685
if self.type.type == "intrinsic" and self.type.name == "void":
645686
# Returns nothing
646687
return []
688+
647689
return [
648690
ir.Return(
649691
type=self.type.render_name(converter),
650-
description=self.comment.returns.strip(),
692+
description=self.comment.get_returns(),
651693
)
652694
]
653695

@@ -669,7 +711,9 @@ def to_ir(
669711
exceptions=[],
670712
# Though perhaps technically true, it looks weird to the user
671713
# (and in the template) if constructors have a return value:
672-
type_params=[x.to_ir(converter) for x in self.typeParameter],
714+
type_params=[
715+
x.to_ir(converter) for x in self.typeParameter or self.typeParameters
716+
],
673717
returns=self.return_type(converter)
674718
if self.kindString != "Constructor signature"
675719
else [],

tests/conftest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import sys
33
from pathlib import Path
44

5+
sys.path.append(str(Path(__file__).parent))
6+
57
import pytest
68
from sphinx.testing.path import path
79

@@ -14,6 +16,12 @@
1416
else:
1517
raise RuntimeError("Couldn't find node_modules")
1618

19+
from sphinx_js.analyzer_utils import search_node_modules
20+
from sphinx_js.typedoc import typedoc_version_info
21+
22+
TYPEDOC = search_node_modules("typedoc", "typedoc/bin/typedoc", "")
23+
TYPEDOC_VERSION = typedoc_version_info(TYPEDOC)[0]
24+
1725

1826
pytest_plugins = "sphinx.testing.fixtures"
1927

tests/test_build_ts/test_build_ts.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from conftest import TYPEDOC_VERSION
2+
13
from tests.testing import SphinxBuildTestCase
24

35

@@ -40,14 +42,17 @@ def test_abstract_extends_and_implements(self):
4042
These are all TypeScript-specific features.
4143
4244
"""
45+
CLASS_COMMENT = (
46+
" A definition of a class\n\n" if TYPEDOC_VERSION >= (0, 23, 0) else ""
47+
)
48+
4349
# The quotes around ClassDefinition() must be some weird decision in
4450
# Sphinx's text output. I don't care if they go away in a future
4551
# version of Sphinx. It doesn't affect the HTML output.
4652
self._file_contents_eq(
4753
"autoclass_class_with_interface_and_supers",
4854
"class ClassWithSupersAndInterfacesAndAbstract()\n"
49-
"\n"
50-
" *abstract*\n"
55+
"\n" + CLASS_COMMENT + " *abstract*\n"
5156
"\n"
5257
' *exported from* "class"\n'
5358
"\n"

tests/test_typedoc_analysis/test_typedoc_analysis.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
from unittest import TestCase
33

44
import pytest
5+
from conftest import TYPEDOC_VERSION
56

67
from sphinx_js.ir import Attribute, Class, Function, Param, Pathname, Return, TypeParam
78
from sphinx_js.renderers import AutoClassRenderer, AutoFunctionRenderer
8-
from sphinx_js.typedoc import Comment, Converter, parse
9+
from sphinx_js.typedoc import Comment, Converter, Summary, parse
910
from tests.testing import NO_MATCH, TypeDocAnalyzerTestCase, TypeDocTestCase, dict_where
1011

1112

@@ -105,7 +106,11 @@ class PathSegmentsTests(TypeDocTestCase):
105106

106107
def commented_object(self, comment, **kwargs):
107108
"""Return the object from ``json`` having the given comment short-text."""
108-
return dict_where(self.json, comment=Comment(shortText=comment), **kwargs)
109+
if TYPEDOC_VERSION >= (0, 23, 0):
110+
comment = Comment(summary=[Summary(kind="text", text=comment)])
111+
else:
112+
comment = Comment(shortText=comment)
113+
return dict_where(self.json, comment=comment, **kwargs)
109114

110115
def commented_object_path(self, comment, **kwargs):
111116
"""Return the path segments of the object with the given comment."""

0 commit comments

Comments
 (0)