Skip to content

Commit bb55592

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 d42bac2 commit bb55592

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
@@ -4547,6 +4547,19 @@ public static function parseDocComments(array $comments): array {
45474547

45484548
return $tags;
45494549
}
4550+
4551+
/**
4552+
* @param DocCommentTag[] $tags
4553+
* @return array<string, ?string> Mapping tag names to the value (or null),
4554+
* if a tag is present multiple times the last value is used
4555+
*/
4556+
public static function makeTagMap(array $tags): array {
4557+
$map = [];
4558+
foreach ($tags as $tag) {
4559+
$map[$tag->name] = $tag->value;
4560+
}
4561+
return $map;
4562+
}
45504563
}
45514564

45524565
// Instances of ExposedDocComment are immutable and do not need to be cloned
@@ -4629,6 +4642,13 @@ function parseFunctionLike(
46294642

46304643
if ($comments) {
46314644
$tags = DocCommentTag::parseDocComments($comments);
4645+
$tagMap = DocCommentTag::makeTagMap($tags);
4646+
4647+
$isDeprecated = array_key_exists('deprecated', $tagMap);
4648+
$verify = !array_key_exists('no-verify', $tagMap);
4649+
$tentativeReturnType = array_key_exists('tentative-return-type', $tagMap);
4650+
$supportsCompileTimeEval = array_key_exists('compile-time-eval', $tagMap);
4651+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
46324652

46334653
foreach ($tags as $tag) {
46344654
switch ($tag->name) {
@@ -4643,18 +4663,6 @@ function parseFunctionLike(
46434663
}
46444664
break;
46454665

4646-
case 'deprecated':
4647-
$isDeprecated = true;
4648-
break;
4649-
4650-
case 'no-verify':
4651-
$verify = false;
4652-
break;
4653-
4654-
case 'tentative-return-type':
4655-
$tentativeReturnType = true;
4656-
break;
4657-
46584666
case 'return':
46594667
$docReturnType = $tag->getType();
46604668
break;
@@ -4667,10 +4675,6 @@ function parseFunctionLike(
46674675
$refcount = $tag->getValue();
46684676
break;
46694677

4670-
case 'compile-time-eval':
4671-
$supportsCompileTimeEval = true;
4672-
break;
4673-
46744678
case 'prefer-ref':
46754679
$varName = $tag->getVariableName();
46764680
if (!isset($paramMeta[$varName])) {
@@ -4679,10 +4683,6 @@ function parseFunctionLike(
46794683
$paramMeta[$varName][$tag->name] = true;
46804684
break;
46814685

4682-
case 'undocumentable':
4683-
$isUndocumentable = true;
4684-
break;
4685-
46864686
case 'frameless-function':
46874687
$framelessFunctionInfos[] = new FramelessFunctionInfo($tag->getValue());
46884688
break;
@@ -4812,26 +4812,19 @@ function parseConstLike(
48124812
array $attributes
48134813
): ConstInfo {
48144814
$phpDocType = null;
4815-
$deprecated = false;
4816-
$cValue = null;
4817-
$link = null;
4818-
$isFileCacheAllowed = true;
4819-
if ($comments) {
4820-
$tags = DocCommentTag::parseDocComments($comments);
4821-
foreach ($tags as $tag) {
4822-
if ($tag->name === 'var') {
4823-
$phpDocType = $tag->getType();
4824-
} elseif ($tag->name === 'deprecated') {
4825-
$deprecated = true;
4826-
} elseif ($tag->name === 'cvalue') {
4827-
$cValue = $tag->value;
4828-
} elseif ($tag->name === 'undocumentable') {
4829-
$isUndocumentable = true;
4830-
} elseif ($tag->name === 'link') {
4831-
$link = $tag->value;
4832-
} elseif ($tag->name === 'no-file-cache') {
4833-
$isFileCacheAllowed = false;
4834-
}
4815+
4816+
$tags = DocCommentTag::parseDocComments($comments);
4817+
$tagMap = DocCommentTag::makeTagMap($tags);
4818+
4819+
$deprecated = array_key_exists('deprecated', $tagMap);
4820+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
4821+
$isFileCacheAllowed = !array_key_exists('no-file-cache', $tagMap);
4822+
$cValue = $tagMap['cvalue'] ?? null;
4823+
$link = $tagMap['link'] ?? null;
4824+
4825+
foreach ($tags as $tag) {
4826+
if ($tag->name === 'var') {
4827+
$phpDocType = $tag->getType();
48354828
}
48364829
}
48374830

@@ -4886,22 +4879,17 @@ function parseProperty(
48864879
array $attributes
48874880
): PropertyInfo {
48884881
$phpDocType = null;
4889-
$isDocReadonly = false;
4890-
$isVirtual = false;
4891-
$link = null;
48924882

4893-
if ($comments) {
4894-
$tags = DocCommentTag::parseDocComments($comments);
4895-
foreach ($tags as $tag) {
4896-
if ($tag->name === 'var') {
4897-
$phpDocType = $tag->getType();
4898-
} elseif ($tag->name === 'readonly') {
4899-
$isDocReadonly = true;
4900-
} elseif ($tag->name === 'link') {
4901-
$link = $tag->value;
4902-
} elseif ($tag->name === 'virtual') {
4903-
$isVirtual = true;
4904-
}
4883+
$tags = DocCommentTag::parseDocComments($comments);
4884+
$tagMap = DocCommentTag::makeTagMap($tags);
4885+
4886+
$isDocReadonly = array_key_exists('readonly', $tagMap);
4887+
$link = $tagMap['link'] ?? null;
4888+
$isVirtual = array_key_exists('virtual', $tagMap);
4889+
4890+
foreach ($tags as $tag) {
4891+
if ($tag->name === 'var') {
4892+
$phpDocType = $tag->getType();
49054893
}
49064894
}
49074895

@@ -4956,25 +4944,18 @@ function parseClass(
49564944
): ClassInfo {
49574945
$comments = $class->getComments();
49584946
$alias = null;
4959-
$isDeprecated = false;
4960-
$isStrictProperties = false;
4961-
$isNotSerializable = false;
49624947
$allowsDynamicProperties = false;
49634948

4964-
if ($comments) {
4965-
$tags = DocCommentTag::parseDocComments($comments);
4966-
foreach ($tags as $tag) {
4967-
if ($tag->name === 'alias') {
4968-
$alias = $tag->getValue();
4969-
} else if ($tag->name === 'deprecated') {
4970-
$isDeprecated = true;
4971-
} else if ($tag->name === 'strict-properties') {
4972-
$isStrictProperties = true;
4973-
} else if ($tag->name === 'not-serializable') {
4974-
$isNotSerializable = true;
4975-
} else if ($tag->name === 'undocumentable') {
4976-
$isUndocumentable = true;
4977-
}
4949+
$tags = DocCommentTag::parseDocComments($comments);
4950+
$tagMap = DocCommentTag::makeTagMap($tags);
4951+
4952+
$isDeprecated = array_key_exists('deprecated', $tagMap);
4953+
$isStrictProperties = array_key_exists('strict-properties', $tagMap);
4954+
$isNotSerializable = array_key_exists('not-serializable', $tagMap);
4955+
$isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
4956+
foreach ($tags as $tag) {
4957+
if ($tag->name === 'alias') {
4958+
$alias = $tag->getValue();
49784959
}
49794960
}
49804961

0 commit comments

Comments
 (0)