Skip to content

Commit a21daa7

Browse files
gen_stub: deduplicate and simplify DocCommentTag processing
For a lot of the structures, the parsing of doc comment tags is based on if a specific tag is present, or the value that it has if it is. Add a new helper method, `DocCommentTag::makeTagMap()`, that turns an array of tag instances into a map from tag name to value (the last value, if there are multiple uses of the same tag name). Then, for the simple cases where just a tag's presence is all that is checked, or just the (last) value is used, check the map instead of using a loop through all of the tags present.
1 parent 194b4df commit a21daa7

File tree

1 file changed

+53
-72
lines changed

1 file changed

+53
-72
lines changed

build/gen_stub.php

Lines changed: 53 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,6 +4520,19 @@ public static function parseDocComments(array $comments): array {
45204520

45214521
return $tags;
45224522
}
4523+
4524+
/**
4525+
* @param DocCommentTag[] $tags
4526+
* @return array<string, ?string> Mapping tag names to the value (or null),
4527+
* if a tag is present multiple times the last value is used
4528+
*/
4529+
public static function makeTagMap(array $tags): array {
4530+
$map = [];
4531+
foreach ($tags as $tag) {
4532+
$map[$tag->name] = $tag->value;
4533+
}
4534+
return $map;
4535+
}
45234536
}
45244537

45254538
// Instances of ExposedDocComment are immutable and do not need to be cloned
@@ -4602,6 +4615,13 @@ function parseFunctionLike(
46024615

46034616
if ($comments) {
46044617
$tags = DocCommentTag::parseDocComments($comments);
4618+
$tagMap = DocCommentTag::makeTagMap($tags);
4619+
4620+
$isDeprecated = array_key_exists('deprecated', $tagMap);
4621+
$verify = !array_key_exists('no-verify', $tagMap);
4622+
$tentativeReturnType = array_key_exists('tentative-return-type', $tagMap);
4623+
$supportsCompileTimeEval = array_key_exists('compile-time-eval', $tagMap);
4624+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
46054625

46064626
foreach ($tags as $tag) {
46074627
switch ($tag->name) {
@@ -4616,18 +4636,6 @@ function parseFunctionLike(
46164636
}
46174637
break;
46184638

4619-
case 'deprecated':
4620-
$isDeprecated = true;
4621-
break;
4622-
4623-
case 'no-verify':
4624-
$verify = false;
4625-
break;
4626-
4627-
case 'tentative-return-type':
4628-
$tentativeReturnType = true;
4629-
break;
4630-
46314639
case 'return':
46324640
$docReturnType = $tag->getType();
46334641
break;
@@ -4640,10 +4648,6 @@ function parseFunctionLike(
46404648
$refcount = $tag->getValue();
46414649
break;
46424650

4643-
case 'compile-time-eval':
4644-
$supportsCompileTimeEval = true;
4645-
break;
4646-
46474651
case 'prefer-ref':
46484652
$varName = $tag->getVariableName();
46494653
if (!isset($paramMeta[$varName])) {
@@ -4652,10 +4656,6 @@ function parseFunctionLike(
46524656
$paramMeta[$varName][$tag->name] = true;
46534657
break;
46544658

4655-
case 'undocumentable':
4656-
$isUndocumentable = true;
4657-
break;
4658-
46594659
case 'frameless-function':
46604660
$framelessFunctionInfos[] = new FramelessFunctionInfo($tag->getValue());
46614661
break;
@@ -4785,26 +4785,19 @@ function parseConstLike(
47854785
array $attributes
47864786
): ConstInfo {
47874787
$phpDocType = null;
4788-
$deprecated = false;
4789-
$cValue = null;
4790-
$link = null;
4791-
$isFileCacheAllowed = true;
4792-
if ($comments) {
4793-
$tags = DocCommentTag::parseDocComments($comments);
4794-
foreach ($tags as $tag) {
4795-
if ($tag->name === 'var') {
4796-
$phpDocType = $tag->getType();
4797-
} elseif ($tag->name === 'deprecated') {
4798-
$deprecated = true;
4799-
} elseif ($tag->name === 'cvalue') {
4800-
$cValue = $tag->value;
4801-
} elseif ($tag->name === 'undocumentable') {
4802-
$isUndocumentable = true;
4803-
} elseif ($tag->name === 'link') {
4804-
$link = $tag->value;
4805-
} elseif ($tag->name === 'no-file-cache') {
4806-
$isFileCacheAllowed = false;
4807-
}
4788+
4789+
$tags = DocCommentTag::parseDocComments($comments);
4790+
$tagMap = DocCommentTag::makeTagMap($tags);
4791+
4792+
$deprecated = array_key_exists('deprecated', $tagMap);
4793+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
4794+
$isFileCacheAllowed = !array_key_exists('no-file-cache', $tagMap);
4795+
$cValue = $tagMap['cvalue'] ?? null;
4796+
$link = $tagMap['link'] ?? null;
4797+
4798+
foreach ($tags as $tag) {
4799+
if ($tag->name === 'var') {
4800+
$phpDocType = $tag->getType();
48084801
}
48094802
}
48104803

@@ -4859,22 +4852,17 @@ function parseProperty(
48594852
array $attributes
48604853
): PropertyInfo {
48614854
$phpDocType = null;
4862-
$isDocReadonly = false;
4863-
$isVirtual = false;
4864-
$link = null;
48654855

4866-
if ($comments) {
4867-
$tags = DocCommentTag::parseDocComments($comments);
4868-
foreach ($tags as $tag) {
4869-
if ($tag->name === 'var') {
4870-
$phpDocType = $tag->getType();
4871-
} elseif ($tag->name === 'readonly') {
4872-
$isDocReadonly = true;
4873-
} elseif ($tag->name === 'link') {
4874-
$link = $tag->value;
4875-
} elseif ($tag->name === 'virtual') {
4876-
$isVirtual = true;
4877-
}
4856+
$tags = DocCommentTag::parseDocComments($comments);
4857+
$tagMap = DocCommentTag::makeTagMap($tags);
4858+
4859+
$isDocReadonly = array_key_exists('readonly', $tagMap);
4860+
$link = $tagMap['link'] ?? null;
4861+
$isVirtual = array_key_exists('virtual', $tagMap);
4862+
4863+
foreach ($tags as $tag) {
4864+
if ($tag->name === 'var') {
4865+
$phpDocType = $tag->getType();
48784866
}
48794867
}
48804868

@@ -4929,25 +4917,18 @@ function parseClass(
49294917
): ClassInfo {
49304918
$comments = $class->getComments();
49314919
$alias = null;
4932-
$isDeprecated = false;
4933-
$isStrictProperties = false;
4934-
$isNotSerializable = false;
49354920
$allowsDynamicProperties = false;
49364921

4937-
if ($comments) {
4938-
$tags = DocCommentTag::parseDocComments($comments);
4939-
foreach ($tags as $tag) {
4940-
if ($tag->name === 'alias') {
4941-
$alias = $tag->getValue();
4942-
} else if ($tag->name === 'deprecated') {
4943-
$isDeprecated = true;
4944-
} else if ($tag->name === 'strict-properties') {
4945-
$isStrictProperties = true;
4946-
} else if ($tag->name === 'not-serializable') {
4947-
$isNotSerializable = true;
4948-
} else if ($tag->name === 'undocumentable') {
4949-
$isUndocumentable = true;
4950-
}
4922+
$tags = DocCommentTag::parseDocComments($comments);
4923+
$tagMap = DocCommentTag::makeTagMap($tags);
4924+
4925+
$isDeprecated = array_key_exists('deprecated', $tagMap);
4926+
$isStrictProperties = array_key_exists('strict-properties', $tagMap);
4927+
$isNotSerializable = array_key_exists('not-serializable', $tagMap);
4928+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
4929+
foreach ($tags as $tag) {
4930+
if ($tag->name === 'alias') {
4931+
$alias = $tag->getValue();
49514932
}
49524933
}
49534934

0 commit comments

Comments
 (0)