Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit 7895d85

Browse files
committed
Add support for types groupping and arrays shortcut, closes #6
1 parent 344583c commit 7895d85

File tree

3 files changed

+318
-16
lines changed

3 files changed

+318
-16
lines changed

‎src/Extractors/ExtractorDefinitionBuilder.php

Lines changed: 119 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,49 @@ class ExtractorDefinitionBuilder implements ExtractorDefinitionBuilderInterface
2727
/**
2828
* @var string
2929
*/
30-
protected $type_regexp = '/^((?<name>[-_\w]+)(?:\s*\(\s*(?<param>(?-3)*|[\w\\\\]+)\s*\))?(?:\s*\|\s*(?<alt>(?-4)))?)$/';
30+
protected $type_regexp = '/
31+
^
32+
(
33+
(?<name>
34+
[-_\w]*
35+
)
36+
(?:
37+
\s*
38+
(?<group>
39+
\(
40+
\s*
41+
(?<param>
42+
(?-4)*
43+
|
44+
[\w\\\\]+
45+
)
46+
\s*
47+
\)
48+
)
49+
)?
50+
(?:
51+
\s*
52+
(?<arr>(?:\s*\[\s*\]\s*)+)
53+
)?
54+
(?:
55+
\s*
56+
\|
57+
\s*
58+
(?<alt>(?-6))
59+
)?
60+
)
61+
$
62+
/xi';
63+
64+
protected $type_regexp2 = '/
65+
^
66+
(?:((\w+\b(?:\(.*\))?(?:\s*\[\s*\])?)(?:\s*\|\s*(?-1))*))
67+
|
68+
(?:\(\s*(?-2)\s*\)(?:\s*\[\s*\])?)
69+
|
70+
(\[\s*\])
71+
$
72+
/xi';
3173

3274
/**
3375
* {@inheritdoc}
@@ -40,32 +82,53 @@ public function build(string $definition): ExtractorDefinitionInterface
4082
throw new ExtractorDefinitionBuilderException('Definition must be non-empty string');
4183
}
4284

43-
if (preg_match($this->type_regexp, $definition, $matches)) {
44-
return $this->buildExtractor($matches['name'], $matches['param'] ?? null, $matches['alt'] ?? null);
85+
try {
86+
if (preg_match($this->type_regexp, $definition, $matches)) {
87+
$extractor = $this->buildExtractor($matches['name'], $matches['param'] ?? '', $matches['alt'] ?? '', $this->getDepth($matches), $this->hasGroups($matches));
88+
89+
return $extractor;
90+
}
91+
} catch (ExtractorDefinitionBuilderException $e) {
92+
// We don't care about what specific issue we hit inside,
93+
// for API user it means that the definition is invalid
4594
}
4695

4796
throw new ExtractorDefinitionBuilderException("Unable to parse definition: '{$definition}'");
4897
}
4998

5099
/**
51-
* @param string $name
100+
* @param string $name
52101
* @param null|string $param
53102
* @param null|string $alt_definitions
103+
* @param int $depth
104+
* @param bool $groups
54105
*
55106
* @return ExtractorDefinitionInterface
56107
* @throws ExtractorDefinitionBuilderException
57108
*/
58-
protected function buildExtractor(string $name, ?string $param, ?string $alt_definitions): ExtractorDefinitionInterface
109+
protected function buildExtractor(string $name, string $param, string $alt_definitions, int$depth, bool$groups): ExtractorDefinitionInterface
59110
{
60111
$next = null;
61112

62-
if ($param && preg_match($this->type_regexp, $param, $matches)) {
63-
$next = $this->buildExtractor($matches['name'], $matches['param'] ?? null, $matches['alt'] ?? null);
113+
if ('' !== $param && preg_match($this->type_regexp, $param, $matches)) {
114+
$next = $this->buildExtractor($matches['name'], $matches['param'] ?? '', $matches['alt'] ?? '', $this->getDepth($matches), $this->hasGroups($matches));
115+
}
116+
117+
if ($name) {
118+
$definition = new PlainExtractorDefinition($name, $next);
119+
} else {
120+
$definition = $next;
121+
}
122+
123+
if ($depth > 0) {
124+
$definition = $this->buildArrayDefinition($definition, $depth, $groups);
64125
}
65126

66-
$definition = new PlainExtractorDefinition($name, $next);
127+
if (!$definition) {
128+
throw new ExtractorDefinitionBuilderException('Empty group is not allowed');
129+
}
67130

68-
if ($alt_definitions) {
131+
if ('' !== $alt_definitions) {
69132
$definition = $this->buildVariableDefinition($definition, $alt_definitions);
70133
}
71134

@@ -74,7 +137,7 @@ protected function buildExtractor(string $name, ?string $param, ?string $alt_def
74137

75138
/**
76139
* @param PlainExtractorDefinitionInterface $definition
77-
* @param string $alt_definitions
140+
* @param string $alt_definitions
78141
*
79142
* @return VariableExtractorDefinition
80143
* @throws ExtractorDefinitionBuilderException
@@ -83,19 +146,61 @@ protected function buildVariableDefinition(PlainExtractorDefinitionInterface $de
83146
{
84147
$alt = [$definition];
85148

86-
while ($alt_definitions && preg_match($this->type_regexp, $alt_definitions, $matches)) {
149+
while ('' !== $alt_definitions && preg_match($this->type_regexp, $alt_definitions, $matches)) {
87150
// build alt
88-
$alt[] = $this->buildExtractor($matches['name'], $matches['param'] ?? null, null);
151+
$alt[] = $this->buildExtractor($matches['name'], $matches['param'] ?? '', '', $this->getDepth($matches), $this->hasGroups($matches));
89152

90-
$alt_definitions = $matches['alt'] ?? null;
153+
$alt_definitions = trim($matches['alt'] ?? '');
91154
}
92155

93-
if ($alt_definitions) {
156+
if ('' !== $alt_definitions) {
157+
// UNEXPECTED
94158
// this should not be possible, but just in case we will ever get here
95159
throw new ExtractorDefinitionBuilderException('Invalid varying definition');
96160
}
97161

98162
return new VariableExtractorDefinition(...$alt);
99163
}
100164

165+
/**
166+
* @param null|ExtractorDefinitionInterface $definition
167+
* @param int $depth
168+
* @param bool $groups
169+
*
170+
* @return ExtractorDefinitionInterface
171+
* @throws ExtractorDefinitionBuilderException
172+
*/
173+
protected function buildArrayDefinition(?ExtractorDefinitionInterface $definition, int $depth, bool $groups): ExtractorDefinitionInterface
174+
{
175+
if (!$definition && $groups) {
176+
throw new ExtractorDefinitionBuilderException('Empty group is not allowed');
177+
}
178+
179+
while ($depth) {
180+
$depth--;
181+
// arrayed definition
182+
$definition = new PlainExtractorDefinition('[]', $definition);
183+
}
184+
185+
return $definition;
186+
}
187+
188+
/**
189+
* @param array $matches
190+
*
191+
* @return int
192+
*/
193+
private function getDepth(array $matches): int
194+
{
195+
if (!isset($matches['arr']) || '' === $matches['arr']) {
196+
return 0;
197+
}
198+
199+
return substr_count($matches['arr'], '[');
200+
}
201+
202+
private function hasGroups(array $matches): bool
203+
{
204+
return isset($matches['group']) && '' !== $matches['group'];
205+
}
101206
}

‎src/Specs/Builder/ParameterSpecBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class ParameterSpecBuilder implements ParameterSpecBuilderInterface
5656
\s*
5757
\:
5858
\s*
59-
(?<type>(\w+\b(?:\(.*\))?)(?:\s*\|\s*(?-1))*)
59+
(?<type>(\w*(?:\(.*\))?(?:\[\s*\])?)(?:\s*\|\s*(?-1))*)
6060
\s*
6161
)?
6262
$

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /