Skip to content

Commit 04ae502

Browse files
Merge branch '3.2'
* 3.2: Make .travis.yml more readable Fold Travis CI output by component [VarDumper] Minor tweaks to html/css dumps Add trhows PHPDoc in Application::run [Debug] Set exit status to 255 on error [HttpFoundation] Store IANA's RNG files in the repository [PropertyInfo] Remove a useless call to count() in SerializerExtractor [PropertyInfo] Prevent returning int values in some cases. [HttpFoundation] Fix getClientIp @return docblock Add @throws phpdoc unify PHPUnit config files
2 parents df155dd + fc195dc commit 04ae502

File tree

20 files changed

+412
-111
lines changed

20 files changed

+412
-111
lines changed

.travis.yml

Lines changed: 132 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -43,63 +43,140 @@ services:
4343
- redis-server
4444

4545
before_install:
46-
- stty cols 120
47-
- mkdir /tmp/slapd
48-
- slapd -f src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf -h ldap://localhost:3389 &
49-
- PHP=$TRAVIS_PHP_VERSION
50-
# Matrix lines for intermediate PHP versions are skipped for pull requests
51-
- if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && ! $PHP = hhvm* && $TRAVIS_PULL_REQUEST != false ]]; then deps=skip; skip=1; fi
52-
# A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line
53-
- if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj; (cd php-$MIN_PHP; ./configure --enable-sigchild --enable-pcntl; make -j2); fi
54-
- if [[ ! $PHP = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi
55-
- if [[ ! $skip ]]; then echo date.timezone = Europe/Paris >> $INI_FILE; fi
56-
- if [[ ! $skip ]]; then echo memory_limit = -1 >> $INI_FILE; fi
57-
- if [[ ! $skip ]]; then echo session.gc_probability = 0 >> $INI_FILE; fi
58-
- if [[ ! $skip ]]; then echo opcache.enable_cli = 1 >> $INI_FILE; fi
59-
- if [[ ! $skip ]]; then echo hhvm.jit = 0 >> $INI_FILE; fi
60-
- if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi
61-
- if [[ ! $skip && $PHP = 5.* ]]; then echo extension = memcache.so >> $INI_FILE; fi
62-
- if [[ ! $skip && $PHP = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.11 && echo apc.enable_cli = 1 >> $INI_FILE); fi
63-
- if [[ ! $skip && $PHP = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.6 && echo apc.enable_cli = 1 >> $INI_FILE); fi
64-
- if [[ ! $deps && $PHP = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> $INI_FILE); fi
65-
- if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = memcached.so >> $INI_FILE; fi
66-
- if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = ldap.so >> $INI_FILE; fi
67-
- if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = redis.so >> $INI_FILE; fi;
68-
- if [[ ! $skip && ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
69-
- if [[ ! $skip ]]; then [ -d ~/.composer ] || mkdir ~/.composer; cp .composer/* ~/.composer/; fi
70-
- if [[ ! $skip ]]; then export PHPUNIT=$(readlink -f ./phpunit); fi
71-
- if [[ ! $skip ]]; then ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif; fi
72-
- if [[ ! $skip ]]; then ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif; fi
46+
- |
47+
# General configuration
48+
stty cols 120
49+
mkdir /tmp/slapd
50+
slapd -f src/Symfony/Component/Ldap/Tests/Fixtures/conf/slapd.conf -h ldap://localhost:3389 &
51+
PHP=$TRAVIS_PHP_VERSION
52+
[ -d ~/.composer ] || mkdir ~/.composer
53+
cp .composer/* ~/.composer/
54+
export PHPUNIT=$(readlink -f ./phpunit)
55+
export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data"
56+
export COMPOSER_UP='composer update --no-progress --no-suggest --ansi'
57+
58+
# tfold is a helper to create folded reports
59+
tfold () {
60+
title=$1
61+
fold=$(echo $title | sed -r 's/[^-_A-Za-z\d]+/./g')
62+
shift
63+
echo -e "travis_fold:start:$fold\\n\\e[1;34m$title\\e[0m"
64+
bash -xc "$*" 2>&1 &&
65+
echo -e "\\e[32mOK\\e[0m $title\\n\\ntravis_fold:end:$fold" ||
66+
( echo -e "\\e[41mKO\\e[0m $title\\n" && exit 1 )
67+
}
68+
export -f tfold
69+
70+
# php.ini configuration
71+
if [[ $PHP = hhvm* ]]; then
72+
INI=/etc/hhvm/php.ini
73+
else
74+
INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
75+
phpenv config-rm xdebug.ini || echo "xdebug not available"
76+
fi
77+
echo date.timezone = Europe/Paris >> $INI
78+
echo memory_limit = -1 >> $INI
79+
echo session.gc_probability = 0 >> $INI
80+
echo opcache.enable_cli = 1 >> $INI
81+
echo hhvm.jit = 0 >> $INI
82+
echo apc.enable_cli = 1 >> $INI
83+
echo extension = ldap.so >> $INI
84+
echo extension = redis.so >> $INI
85+
echo extension = memcached.so >> $INI
86+
[[ $PHP = 5.* ]] && echo extension = mongo.so >> $INI
87+
[[ $PHP = 5.* ]] && echo extension = memcache.so >> $INI
88+
89+
# Matrix lines for intermediate PHP versions are skipped for pull requests
90+
if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && ! $PHP = hhvm* && $TRAVIS_PULL_REQUEST != false ]]; then
91+
deps=skip
92+
skip=1
93+
else
94+
COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
95+
fi
96+
97+
- |
98+
# Install sigchild-enabled PHP to test the Process component on the lowest PHP matrix line
99+
if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then
100+
wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj &&
101+
(cd php-$MIN_PHP && ./configure --enable-sigchild --enable-pcntl && make -j2)
102+
fi
103+
104+
- |
105+
# Install extra PHP extensions
106+
if [[ ! $skip && $PHP = 5.* ]]; then
107+
([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") &&
108+
tfold ext.apcu4 'echo yes | pecl install -f apcu-4.0.11'
109+
elif [[ ! $skip && $PHP = 7.* ]]; then
110+
tfold ext.apcu5 'echo yes | pecl install -f apcu-5.1.6'
111+
fi
112+
113+
- |
114+
# Load fixtures
115+
if [[ ! $skip ]]; then
116+
ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/base.ldif &&
117+
ldapadd -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif
118+
fi
73119
74120
install:
75-
- if [[ ! $skip && $deps ]]; then cp composer.json composer.json.orig; fi
76-
- if [[ ! $skip && $deps ]]; then echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json; fi
77-
- if [[ ! $skip ]]; then COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi
78-
# Create local composer packages for each patched components and reference them in composer.json files when cross-testing components
79-
- if [[ ! $skip && $deps ]]; then php .github/build-packages.php HEAD^ $COMPONENTS; fi
80-
- if [[ ! $skip && $deps ]]; then mv composer.json composer.json.phpunit; mv composer.json.orig composer.json; fi
81-
- if [[ ! $skip && ! $deps ]]; then php .github/build-packages.php HEAD^ src/Symfony/Bridge/PhpUnit; fi
82-
# For the master branch when deps=high, the version before master is checked out and tested with the locally patched components
83-
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//); else SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*'); fi
84-
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then git fetch origin $SYMFONY_VERSION; git checkout -m FETCH_HEAD; COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi
85-
# Legacy tests are skipped when deps=high and when the current branch version has not the same major version number than the next one
86-
- if [[ $deps = high && ${SYMFONY_VERSION%.*} != $(git show $(git ls-remote --heads | grep -FA1 /$SYMFONY_VERSION | tail -n 1):composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9]*' | head -n 1) ]]; then LEGACY=,legacy; fi
87-
- export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev
88-
- if [[ ! $skip && $deps ]]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi
89-
- if [[ ! $skip && $deps ]]; then mv composer.json.phpunit composer.json; fi
90-
- if [[ ! $skip ]]; then composer update --no-suggest; fi
121+
- |
122+
# Create local composer packages for each patched components and reference them in composer.json files when cross-testing components
123+
if [[ ! $deps ]]; then
124+
php .github/build-packages.php HEAD^ src/Symfony/Bridge/PhpUnit
125+
elif [[ ! $skip ]]; then
126+
export SYMFONY_DEPRECATIONS_HELPER=weak &&
127+
cp composer.json composer.json.orig &&
128+
echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json &&
129+
php .github/build-packages.php HEAD^ $COMPONENTS &&
130+
mv composer.json composer.json.phpunit &&
131+
mv composer.json.orig composer.json
132+
fi
133+
134+
- |
135+
# For the master branch, when deps=high, the version before master is checked out and tested with the locally patched components
136+
if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then
137+
SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//) &&
138+
git fetch origin $SYMFONY_VERSION &&
139+
git checkout -m FETCH_HEAD &&
140+
COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
141+
elif [[ ! $skip ]]; then
142+
SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*')
143+
fi
144+
145+
- |
146+
# Legacy tests are skipped when deps=high and when the current branch version has not the same major version number than the next one
147+
[[ $deps = high && ${SYMFONY_VERSION%.*} != $(git show $(git ls-remote --heads | grep -FA1 /$SYMFONY_VERSION | tail -n 1):composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9]*' | head -n 1) ]] && LEGACY=,legacy
148+
149+
export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev
150+
if [[ ! $skip && $deps ]]; then mv composer.json.phpunit composer.json; fi
151+
152+
- if [[ ! $skip ]]; then $COMPOSER_UP; fi
91153
- if [[ ! $skip ]]; then ./phpunit install; fi
92-
- if [[ ! $skip && ! $PHP = hhvm* ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi
154+
- |
155+
# phpinfo
156+
if [[ ! $PHP = hhvm* ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi
157+
158+
- |
159+
run_tests () {
160+
set -e
161+
if [[ $skip ]]; then
162+
echo -e "\\n\\e[1;34mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m"
163+
elif [[ $deps = high ]]; then
164+
echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'"
165+
elif [[ $deps = low ]]; then
166+
echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" &&
167+
# Test the PhpUnit bridge on PHP 5.3, using the original phpunit script
168+
tfold src/Symfony/Bridge/PhpUnit \
169+
"cd src/Symfony/Bridge/PhpUnit && wget https://phar.phpunit.de/phpunit-4.8.phar && phpenv global 5.3 && $COMPOSER_UP && php phpunit-4.8.phar"
170+
elif [[ $PHP = hhvm* ]]; then
171+
$PHPUNIT --exclude-group benchmark,intl-data
172+
else
173+
echo "$COMPONENTS" | parallel --gnu "tfold {} $PHPUNIT_X {}"
174+
tfold tty-group $PHPUNIT --group tty
175+
if [[ $PHP = ${MIN_PHP%.*} ]]; then
176+
echo -e "1\\n0" | xargs -I{} bash -c "tfold src/Symfony/Component/Process.sigchild{} SYMFONY_DEPRECATIONS_HELPER=weak ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/"
177+
fi
178+
fi
179+
}
93180
94181
script:
95-
- REPORT=' && echo -e "\\e[32mOK\\e[0m {}\\n\\n" || (echo -e "\\e[41mKO\\e[0m {}\\n\\n" && $(exit 1))'
96-
- if [[ $skip ]]; then echo -e "\\n\\e[1;34mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m"; fi
97-
- if [[ ! $deps && ! $PHP = hhvm* ]]; then echo "$COMPONENTS" | parallel --gnu '$PHPUNIT --exclude-group tty,benchmark,intl-data {}'"$REPORT"; fi
98-
- if [[ ! $deps && ! $PHP = hhvm* ]]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi
99-
- if [[ ! $deps && $PHP = hhvm* ]]; then $PHPUNIT --exclude-group benchmark,intl-data; fi
100-
- if [[ ! $deps && $PHP = ${MIN_PHP%.*} ]]; then echo -e "1\\n0" | xargs -I{} sh -c 'echo "\\nPHP --enable-sigchild enhanced={}" && SYMFONY_DEPRECATIONS_HELPER=weak ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/'; fi
101-
- if [[ $deps = high ]]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer update --no-progress --no-suggest --ansi; $PHPUNIT --exclude-group tty,benchmark,intl-data'$LEGACY"$REPORT"; fi
102-
- if [[ $deps = low ]]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer update --no-progress --no-suggest --ansi --prefer-lowest --prefer-stable; $PHPUNIT --exclude-group tty,benchmark,intl-data'"$REPORT"; fi
103-
# Test the PhpUnit bridge using the original phpunit script
104-
- if [[ $deps = low ]]; then (cd src/Symfony/Bridge/PhpUnit && wget https://phar.phpunit.de/phpunit-4.8.phar); fi
105-
- if [[ $deps = low ]]; then (cd src/Symfony/Bridge/PhpUnit && phpenv global 5.3 && php --version && composer update && php phpunit-4.8.phar); fi
182+
- (run_tests)

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ a.doc:hover {
6464

6565
.anchor {
6666
position: relative;
67-
top: -7em;
67+
padding-top: 7em;
68+
margin-top: -7em;
6869
visibility: hidden;
6970
}

src/Symfony/Component/Console/Application.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ public function setDispatcher(EventDispatcherInterface $dispatcher)
103103
* @param OutputInterface $output An Output instance
104104
*
105105
* @return int 0 if everything went fine, or an error code
106+
*
107+
* @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}.
106108
*/
107109
public function run(InputInterface $input = null, OutputInterface $output = null)
108110
{

src/Symfony/Component/Console/Command/Command.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ protected function initialize(InputInterface $input, OutputInterface $output)
203203
*
204204
* @return int The command exit code
205205
*
206+
* @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}.
207+
*
206208
* @see setCode()
207209
* @see execute()
208210
*/

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class ErrorHandler
100100
private static $stackedErrors = array();
101101
private static $stackedErrorLevels = array();
102102
private static $toStringException = null;
103+
private static $exitCode = 0;
103104

104105
/**
105106
* Registers the error handler.
@@ -511,6 +512,9 @@ public function handleError($type, $message, $file, $line)
511512
*/
512513
public function handleException($exception, array $error = null)
513514
{
515+
if (null === $error) {
516+
self::$exitCode = 255;
517+
}
514518
if (!$exception instanceof \Exception) {
515519
$exception = new FatalThrowableError($exception);
516520
}
@@ -586,7 +590,7 @@ public static function handleFatalError(array $error = null)
586590
return;
587591
}
588592

589-
if (null === $error) {
593+
if ($exit = null === $error) {
590594
$error = error_get_last();
591595
}
592596

@@ -610,15 +614,21 @@ public static function handleFatalError(array $error = null)
610614
} else {
611615
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
612616
}
613-
} elseif (!isset($exception)) {
614-
return;
615617
}
616618

617619
try {
618-
$handler->handleException($exception, $error);
620+
if (isset($exception)) {
621+
self::$exitCode = 255;
622+
$handler->handleException($exception, $error);
623+
}
619624
} catch (FatalErrorException $e) {
620625
// Ignore this re-throw
621626
}
627+
628+
if ($exit && self::$exitCode) {
629+
$exitCode = self::$exitCode;
630+
register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); });
631+
}
622632
}
623633

624634
/**

src/Symfony/Component/ExpressionLanguage/phpunit.xml.dist

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

3-
<phpunit backupGlobals="false"
4-
backupStaticAttributes="false"
3+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
5+
backupGlobals="false"
56
colors="true"
6-
convertErrorsToExceptions="true"
7-
convertNoticesToExceptions="true"
8-
convertWarningsToExceptions="true"
9-
processIsolation="false"
10-
stopOnFailure="false"
11-
syntaxCheck="false"
127
bootstrap="vendor/autoload.php"
138
failOnRisky="true"
149
failOnWarning="true"

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ public function getClientIps()
888888
* ("Client-Ip" for instance), configure it via "setTrustedHeaderName()" with
889889
* the "client-ip" key.
890890
*
891-
* @return string The client IP address
891+
* @return string|null The client IP address
892892
*
893893
* @see getClientIps()
894894
* @see http://en.wikipedia.org/wiki/X-Forwarded-For

src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ public function ianaCodesReasonPhrasesProvider()
918918
)));
919919

920920
$ianaHttpStatusCodes->load('https://www.iana.org/assignments/http-status-codes/http-status-codes.xml');
921-
if (!$ianaHttpStatusCodes->relaxNGValidate('https://www.iana.org/assignments/http-status-codes/http-status-codes.rng')) {
921+
if (!$ianaHttpStatusCodes->relaxNGValidate(__DIR__.'/schema/http-status-codes.rng')) {
922922
self::fail('Invalid IANA\'s HTTP status code list.');
923923
}
924924

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version='1.0'?>
2+
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
3+
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
4+
ns="http://www.iana.org/assignments">
5+
6+
<include href="iana-registry.rng"/>
7+
8+
<start>
9+
<element name="registry">
10+
<ref name="registryMeta"/>
11+
<element name="registry">
12+
<ref name="registryMeta"/>
13+
<zeroOrMore>
14+
<element name="record">
15+
<optional>
16+
<attribute name="date"><ref name="genericDate"/></attribute>
17+
</optional>
18+
<optional>
19+
<attribute name="updated"><ref name="genericDate"/></attribute>
20+
</optional>
21+
<element name="value"><ref name="genericRange"/></element>
22+
<element name="description"><text/></element>
23+
<ref name="references"/>
24+
</element>
25+
</zeroOrMore>
26+
</element>
27+
<ref name="people"/>
28+
</element>
29+
</start>
30+
31+
</grammar>

0 commit comments

Comments
 (0)