Merge pull request #164 from fenom-template/develop

Fix: parse error if macro defined without arguments
This commit is contained in:
Ivan Shalganov 2015-04-26 22:32:22 +03:00
commit 7f05e13725
3 changed files with 276 additions and 105 deletions

309
composer.lock generated
View File

@ -154,17 +154,125 @@
"time": "2014-08-11 04:32:36"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.14",
"name": "phpdocumentor/reflection-docblock",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94"
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94",
"reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"dflydev/markdown": "~1.0",
"erusev/parsedown": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"phpDocumentor": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"time": "2015-02-03 12:10:50"
},
{
"name": "phpspec/prophecy",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
"shasum": ""
},
"require": {
"doctrine/instantiator": "~1.0,>=1.0.2",
"phpdocumentor/reflection-docblock": "~2.0"
},
"require-dev": {
"phpspec/phpspec": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Prophecy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "http://phpspec.org",
"keywords": [
"Double",
"Dummy",
"fake",
"mock",
"spy",
"stub"
],
"time": "2014-11-17 16:23:49"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.0.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
"shasum": ""
},
"require": {
@ -177,7 +285,7 @@
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "~4.1"
"phpunit/phpunit": "~4"
},
"suggest": {
"ext-dom": "*",
@ -196,9 +304,6 @@
]
},
"notification-url": "https://packagist.org/downloads/",
"include-path": [
""
],
"license": [
"BSD-3-Clause"
],
@ -216,7 +321,7 @@
"testing",
"xunit"
],
"time": "2014-12-26 13:28:33"
"time": "2015-01-24 10:06:35"
},
{
"name": "phpunit/php-file-iterator",
@ -353,16 +458,16 @@
},
{
"name": "phpunit/php-token-stream",
"version": "1.3.0",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876"
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876",
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
"shasum": ""
},
"require": {
@ -375,7 +480,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
"dev-master": "1.4-dev"
}
},
"autoload": {
@ -398,20 +503,20 @@
"keywords": [
"tokenizer"
],
"time": "2014-08-31 06:12:13"
"time": "2015-01-17 09:51:32"
},
{
"name": "phpunit/phpunit",
"version": "4.4.1",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a"
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a",
"reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5",
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5",
"shasum": ""
},
"require": {
@ -421,15 +526,16 @@
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpspec/prophecy": "~1.3.1",
"phpunit/php-code-coverage": "~2.0",
"phpunit/php-file-iterator": "~1.3.2",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "~1.0.2",
"phpunit/phpunit-mock-objects": "~2.3",
"sebastian/comparator": "~1.0",
"sebastian/comparator": "~1.1",
"sebastian/diff": "~1.1",
"sebastian/environment": "~1.1",
"sebastian/exporter": "~1.0",
"sebastian/environment": "~1.2",
"sebastian/exporter": "~1.2",
"sebastian/global-state": "~1.0",
"sebastian/version": "~1.0",
"symfony/yaml": "~2.0"
@ -443,7 +549,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.4.x-dev"
"dev-master": "4.5.x-dev"
}
},
"autoload": {
@ -469,7 +575,7 @@
"testing",
"xunit"
],
"time": "2014-12-28 07:57:05"
"time": "2015-02-05 15:51:19"
},
{
"name": "phpunit/phpunit-mock-objects",
@ -641,25 +747,25 @@
},
{
"name": "sebastian/comparator",
"version": "1.1.0",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "c484a80f97573ab934e37826dba0135a3301b26a"
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a",
"reference": "c484a80f97573ab934e37826dba0135a3301b26a",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e",
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.1",
"sebastian/exporter": "~1.0"
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.1"
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
@ -701,7 +807,7 @@
"compare",
"equality"
],
"time": "2014-11-16 21:32:38"
"time": "2015-01-29 16:28:08"
},
{
"name": "sebastian/diff",
@ -807,28 +913,29 @@
},
{
"name": "sebastian/exporter",
"version": "1.0.2",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0"
"reference": "84839970d05254c73cde183a721c7af13aede943"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943",
"reference": "84839970d05254c73cde183a721c7af13aede943",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": ">=5.3.3",
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.2.x-dev"
}
},
"autoload": {
@ -868,7 +975,7 @@
"export",
"exporter"
],
"time": "2014-09-10 00:51:36"
"time": "2015-01-27 07:23:06"
},
{
"name": "sebastian/global-state",
@ -921,6 +1028,59 @@
],
"time": "2014-10-06 09:23:50"
},
{
"name": "sebastian/recursion-context",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "3989662bbb30a29d20d9faa04a846af79b276252"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252",
"reference": "3989662bbb30a29d20d9faa04a846af79b276252",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2015-01-24 09:48:32"
},
{
"name": "sebastian/version",
"version": "1.0.4",
@ -958,17 +1118,17 @@
},
{
"name": "symfony/config",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Config",
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
"reference": "84c0c150c1520995f09ea9e47e817068b353cb0f"
"reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Config/zipball/84c0c150c1520995f09ea9e47e817068b353cb0f",
"reference": "84c0c150c1520995f09ea9e47e817068b353cb0f",
"url": "https://api.github.com/repos/symfony/Config/zipball/a9f781ba1221067d1f07c8cec0bc50f81b8d7408",
"reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408",
"shasum": ""
},
"require": {
@ -1002,21 +1162,21 @@
],
"description": "Symfony Config Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-21 20:57:55"
},
{
"name": "symfony/console",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8"
"reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8",
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8",
"url": "https://api.github.com/repos/symfony/Console/zipball/e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
"reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
"shasum": ""
},
"require": {
@ -1059,21 +1219,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-25 04:39:26"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216"
"reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216",
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813",
"reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813",
"shasum": ""
},
"require": {
@ -1081,10 +1241,10 @@
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0",
"symfony/config": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/stopwatch": "~2.2"
"symfony/stopwatch": "~2.3"
},
"suggest": {
"symfony/dependency-injection": "",
@ -1117,21 +1277,21 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-02-01 16:10:57"
},
{
"name": "symfony/filesystem",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "ff6efc95256cb33031933729e68b01d720b5436b"
"reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/ff6efc95256cb33031933729e68b01d720b5436b",
"reference": "ff6efc95256cb33031933729e68b01d720b5436b",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/a1f566d1f92e142fa1593f4555d6d89e3044a9b7",
"reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7",
"shasum": ""
},
"require": {
@ -1164,21 +1324,21 @@
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-03 21:13:09"
},
{
"name": "symfony/stopwatch",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Stopwatch",
"source": {
"type": "git",
"url": "https://github.com/symfony/Stopwatch.git",
"reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc"
"reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/261abd360cfb6ac65ea93ffd82073e2011d034fc",
"reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/e8da5286132ba75ce4b4275fbf0f4cd369bfd71c",
"reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c",
"shasum": ""
},
"require": {
@ -1211,21 +1371,21 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-03 08:01:59"
},
{
"name": "symfony/yaml",
"version": "v2.6.1",
"version": "v2.6.4",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20"
"reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20",
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8",
"reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8",
"shasum": ""
},
"require": {
@ -1258,7 +1418,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-25 04:39:26"
}
],
"aliases": [],
@ -1267,6 +1427,7 @@
"satooshi/php-coveralls": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.3.0",
"ext-tokenizer": "*"

View File

@ -925,28 +925,28 @@ class Compiler
if (!$tokens->valid()) {
return;
}
$tokens->next()->need('(')->next();
if ($tokens->is(')')) {
return;
}
while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) {
$param = $tokens->current();
if ($tokens->is(T_VARIABLE)) {
$param = ltrim($param, '$');
}
$tokens->next();
if($tokens->is('(') || !$tokens->isNext(')')){
$tokens->next();
$args[] = $param;
if ($tokens->is('=')) {
$tokens->next();
if ($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) {
$defaults[$param] = $tokens->getAndNext();
} else {
throw new InvalidUsageException("Macro parameters may have only scalar defaults");
while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) {
$param = $tokens->current();
if ($tokens->is(T_VARIABLE)) {
$param = ltrim($param, '$');
}
$tokens->next();
$args[] = $param;
if ($tokens->is('=')) {
$tokens->next();
if ($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) {
$defaults[$param] = $tokens->getAndNext();
} else {
throw new InvalidUsageException("Macro parameters may have only scalar defaults");
}
}
$tokens->skipIf(',');
}
$tokens->skipIf(',');
$tokens->skipIf(')');
}
$tokens->skipIf(')');
$scope["macro"] = array(
"name" => $scope["name"],
"args" => $args,

View File

@ -7,22 +7,28 @@ class MacrosTest extends TestCase
public function setUp()
{
parent::setUp();
$this->tpl(
"math.tpl",
'
{macro plus(x, y)}
x + y = {$x + $y}
{/macro}
$this->tpl("math.tpl",
'{macro plus(x, y)}
x + y = {$x + $y}
{/macro}
{macro minus(x, y, z=0)}
x - y - z = {$x - $y - $z}
{/macro}
{macro minus(x, y, z=0)}
x - y - z = {$x - $y - $z}
{/macro}
{macro multi(x, y)}
x * y = {$x * $y}
{/macro}
{macro multi(x, y)}
x * y = {$x * $y}
{/macro}
Math: {macro.plus x=2 y=3}, {macro.minus x=10 y=4}
{macro e()}
2.71827
{/macro}
{macro pi}
3.14159
{/macro}
Math: {macro.plus x=2 y=3}, {macro.minus x=10 y=4}
'
);
@ -99,6 +105,10 @@ class MacrosTest extends TestCase
exit;
}
/**
* @throws \Exception
* @group macros
*/
public function testMacros()
{
$tpl = $this->fenom->compile('math.tpl');