From 464e964624b44137f570de72fc9826035326fd7c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?=
Date: Thu, 3 Aug 2023 12:39:06 +0200
Subject: [PATCH] always fully resolve classname
---
sphinxcontrib/phpdomain.py | 101 ++++++++++++++++++++++++-------------
test/log.html | 22 ++++++++
test/log.md | 10 ++++
test/log.txt | 17 ++++---
test/rst_doc.html | 3 --
5 files changed, 109 insertions(+), 44 deletions(-)
diff --git a/sphinxcontrib/phpdomain.py b/sphinxcontrib/phpdomain.py
index 3adcb53..0e33e8b 100644
--- a/sphinxcontrib/phpdomain.py
+++ b/sphinxcontrib/phpdomain.py
@@ -216,48 +216,81 @@ def handle_signature(self, sig, signode):
if m is None:
throw_if_false(signode, False, "Invalid signature")
- visibility, modifiers, name_prefix, name, arglist, retann, enumtype = m.groups()
+ visibility, modifiers, classname, name, arglist, retann, enumtype = m.groups()
- if not name_prefix:
- name_prefix = ""
-
- # determine namespace and class name (if applicable), as well as full name
- namespace = self.options.get(
+ # parse & resolve classname and name
+ env_namespace = self.options.get(
"namespace", self.env.temp_data.get("php:namespace")
)
+ env_class = self.env.temp_data.get("php:class")
separator = separators[self.objtype]
-
- if "::" in name_prefix:
- classname = name_prefix.rstrip("::")
+ if (
+ self.objtype == "const"
+ and not classname
+ and (not env_class or name.startswith(NS))
+ ):
+ separator = None
+ type_in_class = separator != None
+
+ if not classname:
+ # throw_if_false(signode, not name.startswith('$'))
+ if name.startswith("$"):
+ name = name[1:]
+ if type_in_class:
+ throw_if_false(signode, env_class, "In-class type requires class")
+ classname = NS + env_class
+ else:
+ classname = name
+ name = None
else:
- classname = self.env.temp_data.get("php:class")
+ throw_if_false(
+ signode, type_in_class, "Unexpected name in non in-class type"
+ )
+ throw_if_false(
+ signode,
+ classname.endswith("::"),
+ "Separator between class and name is required",
+ )
+ classname = classname[:-2]
+ # throw_if_false(signode, name.startswith('$') == (separator and separator.endswith('$'))) # not strictly needed
+ if name.startswith("$"):
+ name = name[1:]
if self.objtype == "global":
- namespace = None
+ name = "$" + classname
classname = None
+ elif classname.startswith(NS):
+ classname = classname[1:]
+ elif env_namespace:
+ classname = env_namespace + NS + classname
+
+ if not type_in_class and self.objtype != "global":
+ name = classname.split(NS)[-1]
+ classname = ""
+ elif classname and env_namespace and classname.startswith(env_namespace + NS):
+ classname = classname[len(env_namespace + NS) :]
+
+ if not classname:
fullname = name
+ elif not name:
+ fullname = classname
else:
- if name_prefix:
- fullname = name_prefix + name
-
- # Currently in a class, but not creating another class,
- elif classname and not self.objtype in [
- "class",
- "exception",
- "interface",
- "trait",
- "enum",
- "function",
- ]:
- if not self.env.temp_data["php:in_class"]:
- name_prefix = classname + separator
-
- fullname = classname + separator + name
+ fullname = classname + separator + name
+
+ name_prefix = classname
+ if not name_prefix:
+ name_prefix = None
+ # elif type_in_class and not self.env.temp_data['php:in_class']:
+ elif type_in_class:
+ if not self.env.temp_data.get("php:in_class", False):
+ name_prefix = name_prefix + separator
else:
- classname = ""
- fullname = name
+ name_prefix = None
+
+ print([env_namespace, classname, name, fullname, name_prefix])
+ print()
- signode["namespace"] = namespace
+ signode["namespace"] = env_namespace
signode["class"] = self.class_name = classname
signode["fullname"] = fullname
@@ -273,16 +306,16 @@ def handle_signature(self, sig, signode):
signode += addnodes.desc_annotation(sig_prefix, sig_prefix)
if name_prefix:
- if namespace and not self.env.temp_data["php:in_class"]:
- name_prefix = namespace + NS + name_prefix
+ if env_namespace and not self.env.temp_data["php:in_class"]:
+ name_prefix = env_namespace + NS + name_prefix
signode += addnodes.desc_addname(name_prefix, name_prefix)
elif (
- namespace
+ env_namespace
and not self.env.temp_data.get("php:in_class", False)
and self.env.config.add_module_names
):
- nodetext = namespace + NS
+ nodetext = env_namespace + NS
signode += addnodes.desc_addname(nodetext, nodetext)
signode += addnodes.desc_name(name, name)
diff --git a/test/log.html b/test/log.html
index b6a2cb3..37d7213 100644
--- a/test/log.html
+++ b/test/log.html
@@ -3,6 +3,28 @@
+
+ In-class type without class
+
+ -
+
+ x()
+
+
+
+
+
+
+ Not In-class type with class
+
+ -
+
+ A::A
+
+
+
+
+
Invalid signature
diff --git a/test/log.md b/test/log.md
index fd11971..56d2e4e 100644
--- a/test/log.md
+++ b/test/log.md
@@ -3,6 +3,16 @@
:::{php:namespacee} Foo
:::
+# In-class type without class
+
+:::{php:method} x()
+:::
+
+# Not In-class type with class
+
+:::{php:class} A::A
+:::
+
# Invalid signature
:::{php:method} x();
diff --git a/test/log.txt b/test/log.txt
index 12ca82b..14db27a 100644
--- a/test/log.txt
+++ b/test/log.txt
@@ -1,11 +1,14 @@
test/log.md:3: WARNING: Unknown directive type: 'php:namespacee' [myst.directive_unknown]
-test/log.md:8: WARNING: [phpdomain] Invalid signature
-test/log.md:13: [phpdomain] Target Foo\Aa not found
-test/log.md:15: [phpdomain] Target Foo\A::simplifyy not found
-test/log.md:20: [phpdomain] Target Foo\Foo\A::simplify not found - did you mean to write A::simplify?
-test/log.md:25: [phpdomain] Target Fooo\Foo\A::simplify not found - did you mean to write \Foo\A::simplify?
-test/ns.md:48: [phpdomain] Target A2::simplify not found
-test/ns.md:53: [phpdomain] Target Bar2\A::simplify not found
+test/log.md:8: WARNING: [phpdomain] In-class type requires class
+test/log.md:13: WARNING: [phpdomain] Unexpected name in non in-class type
+test/log.md:18: WARNING: [phpdomain] Invalid signature
+test/log.md:23: [phpdomain] Target Foo\Aa not found
+test/log.md:25: [phpdomain] Target Foo\A::simplifyy not found
+test/log.md:30: [phpdomain] Target Foo\Foo\A::simplify not found - did you mean to write A::simplify?
+test/log.md:35: [phpdomain] Target Fooo\Foo\A::simplify not found - did you mean to write \Foo\A::simplify?
+test/ns.md:59: [phpdomain] Target A::simplify not found
+test/ns.md:69: [phpdomain] Target A2::simplify not found
+test/ns.md:74: [phpdomain] Target Bar2\A::simplify not found
test/rst_doc.md:506: [phpdomain] Target OtherLibrary\int|string|ReturnedClass|\LibraryName\SubPackage\SubpackageInterface|null not found
test/rst_doc2.md:11: [phpdomain] Target Imagine\Image\ImageInterface::draw not found
test/rst_doc2.md:17: [phpdomain] Target Imagine\Image\PointInterface not found
diff --git a/test/rst_doc.html b/test/rst_doc.html
index e6dfa1a..5010854 100644
--- a/test/rst_doc.html
+++ b/test/rst_doc.html
@@ -687,9 +687,6 @@ Namespaced elements
-
-
- LibraryClass::
-
instanceMethod