diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4c715e..2f1a263 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,8 @@ name: CI on: pull_request: push: + schedule: + - cron: '0 0/2 * * *' jobs: build: @@ -10,9 +12,13 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - # Builds are failing with py3.9+ because sphinx templates are different. - # python: ['3.7', '3.8', '3.9', '3.10', '3.11'] - python: ['3.7', '3.8'] + python: + - '3.7' + - '3.8' + - '3.9' + - '3.10' + - 'latest' # hardcoded below as '3.11' + - 'beta' # hardcoded below as '3.12' fail-fast: false permissions: @@ -23,7 +29,8 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: ${{ matrix.python }} + python-version: ${{ matrix.python == 'latest' && '3.11' || (matrix.python == 'beta' && '3.12' || matrix.python) }} + allow-prereleases: true - name: Install tools run: | @@ -41,28 +48,29 @@ jobs: cd test find . -name '*.html' -exec rm {} \; - sed -i 's~, "log\.md"~~' conf.py - make html SPHINXOPTS='' 2>&1 | tee log.txt + sed -i 's~, "logging\.md"~~' conf.py + make html SPHINXOPTS='' 2>&1 | tee baseline.txt git restore conf.py (cd _build/html && rm genindex.html index.html search.html php-modindex.html) (cd _build/html && find . -name '*.html' -exec sh -c 'xmllint {} --xpath '"'"'//div[@role="main"]'"'"' | xmllint --format - > ../../{}' \;) - sed -i -r 's~.*/(test/)~\1~;t;d' log.txt + sed -i -r 's~[^:]*/(test/)~\1~;t;d' baseline.txt - name: Apply Coding Style - if: matrix.python == '3.11' + if: matrix.python == 'latest' run: | pip install black python -m black . - name: Diff Unit Tests Output and Coding Style + if: matrix.python == 'latest' run: | cd test rm -r _build git add . -N && git diff --exit-code - name: Push Unit Tests Output - if: failure() && github.repository_owner != 'markstory' && matrix.python == '3.11' + if: failure() && github.repository_owner != 'markstory' && matrix.python == 'latest' uses: stefanzweifel/git-auto-commit-action@v4 with: branch: ${{ github.head_ref || github.ref_name }}.changes @@ -78,7 +86,7 @@ jobs: cd test make html SPHINXOPTS='-W' - sed -i 's~, "log\.md"~~' conf.py + sed -i 's~, "logging\.md"~~' conf.py ! make html SPHINXOPTS='-W' || (echo 'Unexpected zero exit code'; false) git restore conf.py diff --git a/.gitignore b/.gitignore index c28a058..45343f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ dist/ build/ doc/_build +test/out test/_build *.pyc *.egg-info diff --git a/setup.py b/setup.py index e6039e2..8d048f8 100644 --- a/setup.py +++ b/setup.py @@ -28,14 +28,14 @@ """ setup( - name='sphinxcontrib-phpdomain', - version='0.11.2', - url='https://github.com/markstory/sphinxcontrib-phpdomain', - download_url='http://pypi.python.org/pypi/sphinxcontrib-phpdomain', - license='BSD', - author='Mark Story', - author_email='mark@mark-story.com', - description='Sphinx extension to enable documenting PHP code', + name="sphinxcontrib-phpdomain", + version="0.11.2", + url="https://github.com/markstory/sphinxcontrib-phpdomain", + download_url="http://pypi.python.org/pypi/sphinxcontrib-phpdomain", + license="BSD", + author="Mark Story", + author_email="mark@mark-story.com", + description="Sphinx extension to enable documenting PHP code", long_description=long_desc, project_urls={ "Documentation": "https://markstory.github.io/sphinxcontrib-phpdomain/", diff --git a/sphinxcontrib/phpdomain.py b/sphinxcontrib/phpdomain.py index 8dc5e84..0ca75e2 100644 --- a/sphinxcontrib/phpdomain.py +++ b/sphinxcontrib/phpdomain.py @@ -1,6 +1,6 @@ """ Sphinx PHP domain. - + The PHP domain. Based off of the rubydomain by SHIBUKAWA Yoshiki :copyright: Copyright 2016 by Mark Story @@ -218,48 +218,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() - - if not name_prefix: - name_prefix = "" + visibility, modifiers, classname, name, arglist, retann, enumtype = m.groups() - # 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 @@ -275,16 +308,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/baseline.txt b/test/baseline.txt new file mode 100644 index 0000000..fc2e4c1 --- /dev/null +++ b/test/baseline.txt @@ -0,0 +1,15 @@ +test/logging.md:8: WARNING: [phpdomain] In-class type requires class +test/logging.md:13: WARNING: [phpdomain] Unexpected name in non in-class type +test/logging.md:18: WARNING: [phpdomain] Invalid signature +test/logging.md:23: [phpdomain] Target Foo\Aa not found +test/logging.md:25: [phpdomain] Target Foo\A::simplifyy not found +test/logging.md:30: [phpdomain] Target Foo\Foo\A::simplify not found - did you mean to write A::simplify? +test/logging.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 +test/rst_doc2.md:17: [phpdomain] Target Imagine\Image\BoxInterface not found +test/rst_doc2.md:17: [phpdomain] Target Imagine\Image\Color not found diff --git a/test/conf.py b/test/conf.py index 2be6ab3..208bb41 100644 --- a/test/conf.py +++ b/test/conf.py @@ -12,6 +12,6 @@ source_suffix = ".md" master_doc = "index" -exclude_patterns = ["_build", "log.md"] +exclude_patterns = ["_build", "logging.md"] html_theme = "default" diff --git a/test/log.txt b/test/log.txt deleted file mode 100644 index 12ca82b..0000000 --- a/test/log.txt +++ /dev/null @@ -1,13 +0,0 @@ -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/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 -test/rst_doc2.md:17: [phpdomain] Target Imagine\Image\BoxInterface not found -test/rst_doc2.md:17: [phpdomain] Target Imagine\Image\Color not found diff --git a/test/log.html b/test/logging.html similarity index 61% rename from test/log.html rename to test/logging.html index b6a2cb3..49376d8 100644 --- a/test/log.html +++ b/test/logging.html @@ -1,10 +1,32 @@
-

Invalid domain type

+

Invalid domain type

+
+
+

In-class type without class

+
+
+ + x() + +
+
+
+
+
+

Not In-class type with class

+
+
+ + A::A + +
+
+
-

Invalid signature

+

Invalid signature

@@ -15,7 +37,7 @@

Invalid signature -

Unresolved references

+

Unresolved references

  • @@ -32,8 +54,7 @@

    Unresolved references

- -
-

Cross linking

+

Cross linking

- -