Skip to content

Commit 88859c8

Browse files
authored
Add support for constants in attribute formatting (#255)
* add support for constants in attribute formatting
1 parent 3c077f9 commit 88859c8

6 files changed

Lines changed: 181 additions & 31 deletions

File tree

phpdotnet/phd/Package/Generic/XHTML.php

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,12 +1449,7 @@ public function format_fieldsynopsis($open, $name, $attrs) {
14491449
public function format_fieldsynopsis_modifier_text($value, $tag) {
14501450
$this->cchunk["fieldsynopsis"]["modifier"] = trim($value);
14511451
if ($this->getRole() === "attribute") {
1452-
$attribute = trim(strtolower($value), "#[]\\");
1453-
$href = Format::getFilename("class.$attribute");
1454-
if ($href) {
1455-
return '<a href="' . $href . $this->getExt() . '">' .$value. '</a> ';
1456-
}
1457-
return false;
1452+
return $this->format_attribute_modifier_text($value);
14581453
}
14591454
return $this->TEXT($value);
14601455
}
@@ -1492,15 +1487,31 @@ public function format_methodparam_modifier($open, $name, $attrs, $props) {
14921487

14931488
public function format_modifier_text($value, $tag) {
14941489
if ($this->getRole() === "attribute") {
1495-
$attribute = trim(strtolower($value), "#[]\\");
1496-
$href = Format::getFilename("class.$attribute");
1497-
if ($href) {
1498-
return '<a href="' . $href . $this->getExt() . '">' .$value. '</a> ';
1499-
}
1490+
return $this->format_attribute_modifier_text($value);
15001491
}
15011492
return false;
15021493
}
15031494

1495+
private function format_attribute_modifier_text(string $value): string {
1496+
// Anything that is not a leading "#[\Attribute(" / "#[\Attribute]" chunk
1497+
// e.g. "|" separator between arguments passes through.
1498+
if (!preg_match('/^(#\[)(.+?)([](])$/', $value, $match)) {
1499+
if (trim($value) === '|') {
1500+
return ' | ';
1501+
}
1502+
return $value;
1503+
}
1504+
1505+
[, $prefix, $name, $suffix] = $match;
1506+
$attribute = strtolower(ltrim($name, "\\"));
1507+
$href = $this->getFilename('class.' . $attribute);
1508+
if (!$href) {
1509+
return $value;
1510+
}
1511+
1512+
return $prefix . '<a href="' . $href . $this->getExt() . '">' . $name . '</a>' . $suffix;
1513+
}
1514+
15041515
public function format_methodsynopsis($open, $name, $attrs, $props) {
15051516
if ($open) {
15061517

@@ -1909,6 +1920,9 @@ public function format_screen($open, $name, $attrs) {
19091920
}
19101921
public function format_constant($open, $name, $attrs, $props)
19111922
{
1923+
if ($this->getRole() === "attribute") {
1924+
return "";
1925+
}
19121926
if ($open) {
19131927
if (str_contains($props["innerXml"], '<replaceable')) {
19141928
$this->pushRole("constant_group");

tests/package/generic/attribute_formatting_001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Content:
4242

4343
<div class="section">
4444
<p class="para">2. Class methodparameter with known attribute</p>
45-
<div class="constructorsynopsis dc-description"><span class="modifier">public</span> <span class="methodname">mysqli::__construct</span>(<span class="methodparam"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><span class="type"><span class="type">string</span><span class="type">null</span></span> <code class="parameter">$password</code><span class="initializer"> = <span class="type">null</span></span></span>)</div>
45+
<div class="constructorsynopsis dc-description"><span class="modifier">public</span> <span class="methodname">mysqli::__construct</span>(<span class="methodparam"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><span class="type"><span class="type">string</span><span class="type">null</span></span> <code class="parameter">$password</code><span class="initializer"> = <span class="type">null</span></span></span>)</div>
4646

4747
</div>
4848

@@ -54,7 +54,7 @@ Content:
5454

5555
<div class="section">
5656
<p class="para">4. Function parameter with known attribute</p>
57-
<div class="methodsynopsis dc-description"><span class="type">bool</span> <span class="methodname">password_verify</span>(<span class="methodparam"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><span class="type">string</span> <code class="parameter">$password</code></span>, <span class="methodparam"><span class="type">string</span> <code class="parameter">$hash</code></span>)</div>
57+
<div class="methodsynopsis dc-description"><span class="type">bool</span> <span class="methodname">password_verify</span>(<span class="methodparam"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><span class="type">string</span> <code class="parameter">$password</code></span>, <span class="methodparam"><span class="type">string</span> <code class="parameter">$hash</code></span>)</div>
5858

5959
</div>
6060
</div>

tests/package/generic/attribute_formatting_002.phpt

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ Content:
6262
<p class="para">2. Class with known attributes</p>
6363
<div class="classsynopsis"><div class="classsynopsisinfo">
6464

65-
<span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
66-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
65+
<span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
66+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
6767
<span class="modifier">class</span> <strong class="classname">DateTime</strong>
6868
{</div>
6969
}</div>
@@ -80,8 +80,8 @@ Content:
8080

8181
<div class="section">
8282
<p class="para">4. Method with known attributes</p>
83-
<div class="methodsynopsis dc-description"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
84-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
83+
<div class="methodsynopsis dc-description"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
84+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
8585
<span class="modifier">public</span> <span class="methodname">ClassName::methodName</span>()</div>
8686

8787
</div>
@@ -96,8 +96,8 @@ Content:
9696

9797
<div class="section">
9898
<p class="para">6. Constructor with known attributes</p>
99-
<div class="constructorsynopsis dc-description"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
100-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
99+
<div class="constructorsynopsis dc-description"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
100+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
101101
<span class="modifier">public</span> <span class="methodname">ClassName::__construct</span>()</div>
102102

103103
</div>
@@ -130,21 +130,21 @@ Content:
130130
<p class="para">8. Class, constructor and methods with known attributes</p>
131131
<div class="classsynopsis"><div class="classsynopsisinfo">
132132

133-
<span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
134-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
133+
<span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
134+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
135135
<span class="modifier">class</span> <strong class="classname">DateTime</strong>
136136
{</div>
137137
<div class="constructorsynopsis dc-description">
138-
<span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
139-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
138+
<span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
139+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
140140
<span class="modifier">public</span> <span class="methodname">ClassName::__construct</span>()</div>
141141

142-
<div class="methodsynopsis dc-description"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
143-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
142+
<div class="methodsynopsis dc-description"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
143+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
144144
<span class="modifier">public</span> <span class="methodname">ClassName::methodName1</span>()</div>
145145

146-
<div class="methodsynopsis dc-description"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
147-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
146+
<div class="methodsynopsis dc-description"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
147+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
148148
<span class="modifier">public</span> <span class="methodname">ClassName::methodName2</span>()</div>
149149

150150
}</div>
@@ -161,8 +161,8 @@ Content:
161161

162162
<div class="section">
163163
<p class="para">10. Function with known attributes</p>
164-
<div class="methodsynopsis dc-description"><span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
165-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
164+
<div class="methodsynopsis dc-description"><span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
165+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
166166
<span class="type">void</span> <span class="methodname">function_name</span>)</div>
167167

168168
</div>

tests/package/generic/attribute_formatting_003.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ Content:
7575
{</div>
7676
<div class="classsynopsisinfo classsynopsisinfo_comment">/* Properties/Constants */</div>
7777
<div class="fieldsynopsis">
78-
<span class="attribute"><a href="file.knownattribute.is.in.html">#[\KnownAttribute]</a> </span><br>
79-
<span class="attribute"><a href="file.anotherknownattribute.is.in.html">#[\AnotherKnownAttribute]</a> </span><br>
78+
<span class="attribute">#[<a href="file.knownattribute.is.in.html">\KnownAttribute</a>]</span><br>
79+
<span class="attribute">#[<a href="file.anotherknownattribute.is.in.html">\AnotherKnownAttribute</a>]</span><br>
8080
<span class="modifier">public</span>
8181
<span class="modifier">readonly</span>
8282
<span class="type">string</span>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
--TEST--
2+
Attribute formatting 004 - Attribute with constant arguments
3+
--FILE--
4+
<?php
5+
namespace phpdotnet\phd;
6+
7+
require_once __DIR__ . "/../../setup.php";
8+
9+
$xmlFile = __DIR__ . "/data/attribute_formatting_004.xml";
10+
11+
$config->xmlFile = $xmlFile;
12+
13+
$format = new TestGenericChunkedXHTML($config, $outputHandler);
14+
15+
$format->SQLiteIndex(
16+
null, null,
17+
"class.attribute",
18+
"class.attribute",
19+
"", "", "", "", "", "", 0,
20+
);
21+
$format->SQLiteIndex(
22+
null, null,
23+
"attribute.constants.target-class",
24+
"class.attribute",
25+
"", "", "", "", "", "", 0,
26+
);
27+
$format->SQLiteIndex(
28+
null, null,
29+
"attribute.constants.target-class-constant",
30+
"class.attribute",
31+
"", "", "", "", "", "", 0,
32+
);
33+
$format->SQLiteIndex(
34+
null, null,
35+
"attribute.constants.target-property",
36+
"class.attribute",
37+
"", "", "", "", "", "", 0,
38+
);
39+
40+
$render = new TestRender(new Reader($outputHandler), $config, $format);
41+
42+
$render->run();
43+
?>
44+
--EXPECT--
45+
Filename: attribute-formatting-004.html
46+
Content:
47+
<div id="attribute-formatting-004" class="chapter">
48+
<div class="section">
49+
<p class="para">1. Attribute with one constant argument</p>
50+
<div class="classsynopsis"><div class="classsynopsisinfo">
51+
52+
<span class="attribute">#[<a href="class.attribute.html">\Attribute</a>(<a href="class.attribute.html#attribute.constants.target-class">Attribute::TARGET_CLASS</a>)]</span><br>
53+
<span class="modifier">final</span>
54+
<span class="modifier">class</span> <strong class="classname">Attribute</strong>
55+
{</div>
56+
}</div>
57+
</div>
58+
59+
<div class="section">
60+
<p class="para">2. Attribute with multiple constant arguments</p>
61+
<div class="classsynopsis"><div class="classsynopsisinfo">
62+
63+
<span class="attribute">#[<a href="class.attribute.html">\Attribute</a>(<a href="class.attribute.html#attribute.constants.target-class-constant">Attribute::TARGET_CLASS_CONSTANT</a> | <a href="class.attribute.html#attribute.constants.target-property">Attribute::TARGET_PROPERTY</a>)]</span><br>
64+
<span class="modifier">final</span>
65+
<span class="modifier">class</span> <strong class="classname">Attribute</strong>
66+
{</div>
67+
}</div>
68+
</div>
69+
70+
<div class="section">
71+
<p class="para">3. Attribute with unknown constant argument</p>
72+
<div class="classsynopsis"><div class="classsynopsisinfo">
73+
74+
<span class="attribute">#[<a href="class.attribute.html">\Attribute</a>(Attribute::TARGET_UNKNOWN)]</span><br>
75+
<span class="modifier">final</span>
76+
<span class="modifier">class</span> <strong class="classname">Attribute</strong>
77+
{</div>
78+
}</div>
79+
</div>
80+
81+
<div class="section">
82+
<p class="para">4. Unknown attribute with constant argument</p>
83+
<div class="classsynopsis"><div class="classsynopsisinfo">
84+
85+
<span class="attribute">#[\UnknownAttribute(<a href="class.attribute.html#attribute.constants.target-class">Attribute::TARGET_CLASS</a>)]</span><br>
86+
<span class="modifier">final</span>
87+
<span class="modifier">class</span> <strong class="classname">Attribute</strong>
88+
{</div>
89+
}</div>
90+
</div>
91+
</div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<chapter xml:id="attribute-formatting-004">
2+
<section>
3+
<para>1. Attribute with one constant argument</para>
4+
<classsynopsis class="class">
5+
<ooclass>
6+
<modifier role="attribute">#[\Attribute(<constant>Attribute::TARGET_CLASS</constant>)]</modifier>
7+
<modifier>final</modifier>
8+
<classname>Attribute</classname>
9+
</ooclass>
10+
</classsynopsis>
11+
</section>
12+
13+
<section>
14+
<para>2. Attribute with multiple constant arguments</para>
15+
<classsynopsis class="class">
16+
<ooclass>
17+
<modifier role="attribute">#[\Attribute(<constant>Attribute::TARGET_CLASS_CONSTANT</constant>|<constant>Attribute::TARGET_PROPERTY</constant>)]</modifier>
18+
<modifier>final</modifier>
19+
<classname>Attribute</classname>
20+
</ooclass>
21+
</classsynopsis>
22+
</section>
23+
24+
<section>
25+
<para>3. Attribute with unknown constant argument</para>
26+
<classsynopsis class="class">
27+
<ooclass>
28+
<modifier role="attribute">#[\Attribute(<constant>Attribute::TARGET_UNKNOWN</constant>)]</modifier>
29+
<modifier>final</modifier>
30+
<classname>Attribute</classname>
31+
</ooclass>
32+
</classsynopsis>
33+
</section>
34+
35+
<section>
36+
<para>4. Unknown attribute with constant argument</para>
37+
<classsynopsis class="class">
38+
<ooclass>
39+
<modifier role="attribute">#[\UnknownAttribute(<constant>Attribute::TARGET_CLASS</constant>)]</modifier>
40+
<modifier>final</modifier>
41+
<classname>Attribute</classname>
42+
</ooclass>
43+
</classsynopsis>
44+
</section>
45+
</chapter>

0 commit comments

Comments
 (0)