mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-09 16:36:31 +02:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
c4bbc8e236 | |||
f78af2c9c8 | |||
950ada4cba |
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,8 +1,16 @@
|
||||
Version 1.4.1-dev
|
||||
Version 1.4.2-dev
|
||||
-----------------
|
||||
|
||||
Nothing yet.
|
||||
|
||||
Version 1.4.1 (2015-09-19)
|
||||
--------------------------
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed issue with too many newlines being stripped at the end of heredoc/nowdoc strings in some
|
||||
cases. (#227)
|
||||
|
||||
Version 1.4.0 (2015-07-14)
|
||||
--------------------------
|
||||
|
||||
|
@ -145,7 +145,7 @@ function resolveMacros($code) {
|
||||
if ('parseEncapsedDoc' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace(\'~(\r\n|\n|\r)$~\', \'\', $s); if (\'\' === $s) array_pop(' . $args[0] . ');';
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace(\'~(\r\n|\n|\r)\z~\', \'\', $s); if (\'\' === $s) array_pop(' . $args[0] . ');';
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
|
@ -107,7 +107,7 @@ class String_ extends Scalar
|
||||
*/
|
||||
public static function parseDocString($startToken, $str) {
|
||||
// strip last newline (thanks tokenizer for sticking it into the string!)
|
||||
$str = preg_replace('~(\r\n|\n|\r)$~', '', $str);
|
||||
$str = preg_replace('~(\r\n|\n|\r)\z~', '', $str);
|
||||
|
||||
// nowdoc string
|
||||
if (false !== strpos($startToken, '\'')) {
|
||||
|
@ -2573,7 +2573,7 @@ class Parser extends ParserAbstract
|
||||
}
|
||||
|
||||
protected function reduceRule379() {
|
||||
foreach ($this->semStack[$this->stackPos-(3-2)] as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace('~(\r\n|\n|\r)$~', '', $s); if ('' === $s) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes);
|
||||
foreach ($this->semStack[$this->stackPos-(3-2)] as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace('~(\r\n|\n|\r)\z~', '', $s); if ('' === $s) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes);
|
||||
}
|
||||
|
||||
protected function reduceRule380() {
|
||||
|
@ -444,7 +444,7 @@ abstract class ParserAbstract
|
||||
private function getNamespacingStyle(array $stmts) {
|
||||
$style = null;
|
||||
$hasNotAllowedStmts = false;
|
||||
foreach ($stmts as $stmt) {
|
||||
foreach ($stmts as $i => $stmt) {
|
||||
if ($stmt instanceof Node\Stmt\Namespace_) {
|
||||
$currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace';
|
||||
if (null === $style) {
|
||||
@ -455,9 +455,21 @@ abstract class ParserAbstract
|
||||
} elseif ($style !== $currentStyle) {
|
||||
throw new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $stmt->getLine());
|
||||
}
|
||||
} elseif (!$stmt instanceof Node\Stmt\Declare_ && !$stmt instanceof Node\Stmt\HaltCompiler) {
|
||||
$hasNotAllowedStmts = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* declare() and __halt_compiler() can be used before a namespace declaration */
|
||||
if ($stmt instanceof Node\Stmt\Declare_ || $stmt instanceof Node\Stmt\HaltCompiler) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* There may be a hashbang line at the very start of the file */
|
||||
if ($i == 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Everything else if forbidden before namespace declarations */
|
||||
$hasNotAllowedStmts = true;
|
||||
}
|
||||
return $style;
|
||||
}
|
||||
|
58
test/code/parser/scalar/docStringNewlines.test
Normal file
58
test/code/parser/scalar/docStringNewlines.test
Normal file
@ -0,0 +1,58 @@
|
||||
Trailing newlines in doc strings
|
||||
-----
|
||||
<?php
|
||||
|
||||
<<<'EOF'@@{ "\n\n" }@@EOF;
|
||||
<<<'EOF'@@{ "\n\n\n" }@@EOF;
|
||||
<<<'EOF'@@{ "\nFoo\n\n" }@@EOF;
|
||||
<<<EOF@@{ "\n\$var\n\n" }@@EOF;
|
||||
|
||||
<<<'EOF'@@{ "\r\n\r\n" }@@EOF;
|
||||
<<<'EOF'@@{ "\r\n\r\n\r\n" }@@EOF;
|
||||
<<<'EOF'@@{ "\r\nFoo\r\n\r\n" }@@EOF;
|
||||
<<<EOF@@{ "\r\n\$var\r\n\r\n" }@@EOF;
|
||||
|
||||
// comment to force line break before EOF
|
||||
-----
|
||||
array(
|
||||
0: Scalar_String(
|
||||
value:
|
||||
)
|
||||
1: Scalar_String(
|
||||
value:
|
||||
|
||||
)
|
||||
2: Scalar_String(
|
||||
value: Foo
|
||||
|
||||
)
|
||||
3: Scalar_Encapsed(
|
||||
parts: array(
|
||||
0: Expr_Variable(
|
||||
name: var
|
||||
)
|
||||
1:
|
||||
|
||||
)
|
||||
)
|
||||
4: Scalar_String(
|
||||
value:
|
||||
)
|
||||
5: Scalar_String(
|
||||
value:
|
||||
|
||||
)
|
||||
6: Scalar_String(
|
||||
value: Foo
|
||||
|
||||
)
|
||||
7: Scalar_Encapsed(
|
||||
parts: array(
|
||||
0: Expr_Variable(
|
||||
name: var
|
||||
)
|
||||
1:
|
||||
|
||||
)
|
||||
)
|
||||
)
|
22
test/code/parser/stmt/namespace/nsAfterHashbang.test
Normal file
22
test/code/parser/stmt/namespace/nsAfterHashbang.test
Normal file
@ -0,0 +1,22 @@
|
||||
Hashbang followed by namespace declaration
|
||||
-----
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
namespace A;
|
||||
-----
|
||||
array(
|
||||
0: Stmt_InlineHTML(
|
||||
value: #!/usr/bin/env php
|
||||
|
||||
)
|
||||
1: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
Reference in New Issue
Block a user