Page MenuHomePhabricator

D21455.diff
No OneTemporary

D21455.diff

diff --git a/src/lint/linter/xhpast/rules/__tests__/formatted-string/formatted-string.lint-test b/src/lint/linter/xhpast/rules/__tests__/formatted-string/formatted-string.lint-test
--- a/src/lint/linter/xhpast/rules/__tests__/formatted-string/formatted-string.lint-test
+++ b/src/lint/linter/xhpast/rules/__tests__/formatted-string/formatted-string.lint-test
@@ -14,6 +14,16 @@
pht('x %s y');
pht('x %s y'.'z');
+
+pht(<<<HEREDOC
+a b c
+HEREDOC
+ );
+
+pht(<<<HEREDOC
+a %s c
+HEREDOC
+ );
~~~~~~~~~~
error:3:1:XHP54:Formatted String
error:7:1:XHP54:Formatted String
@@ -22,6 +32,7 @@
error:13:1:XHP54:Formatted String
error:15:1:XHP54:Formatted String
error:16:1:XHP54:Formatted String
+error:23:1:XHP54:Formatted String
~~~~~~~~~~
~~~~~~~~~~
{
diff --git a/src/parser/xhpast/api/XHPASTNode.php b/src/parser/xhpast/api/XHPASTNode.php
--- a/src/parser/xhpast/api/XHPASTNode.php
+++ b/src/parser/xhpast/api/XHPASTNode.php
@@ -33,7 +33,9 @@
return $this->getChildByIndex(0)->evalStatic();
break;
case 'n_STRING_SCALAR':
- return (string)$this->getStringLiteralValue();
+ return phutil_string_cast($this->getStringLiteralValue());
+ case 'n_HEREDOC':
+ return phutil_string_cast($this->getStringLiteralValue());
case 'n_NUMERIC_SCALAR':
$value = $this->getSemanticString();
if (preg_match('/^0x/i', $value)) {
@@ -186,31 +188,51 @@
}
public function getStringLiteralValue() {
- if ($this->getTypeName() != 'n_STRING_SCALAR') {
- return null;
+ $type_name = $this->getTypeName();
+
+ if ($type_name === 'n_HEREDOC') {
+ $value = $this->getSemanticString();
+ $value = phutil_split_lines($value);
+ $value = array_slice($value, 1, -1);
+ $value = implode('', $value);
+
+ // Strip the final newline from value, this isn't part of the string
+ // literal.
+ $value = preg_replace('/(\r|\n|\r\n)\z/', '', $value);
+
+ return $this->newStringLiteralFromSemanticString($value);
}
- $value = $this->getSemanticString();
- $type = $value[0];
- $value = preg_replace('/^b?[\'"]|[\'"]$/i', '', $value);
- $esc = false;
- $len = strlen($value);
- $out = '';
-
- if ($type == "'") {
- // Single quoted strings treat everything as a literal except "\\" and
- // "\'".
- return str_replace(
- array('\\\\', '\\\''),
- array('\\', "'"),
- $value);
+ if ($type_name === 'n_STRING_SCALAR') {
+ $value = $this->getSemanticString();
+ $type = $value[0];
+ $value = preg_replace('/^b?[\'"]|[\'"]$/i', '', $value);
+
+ if ($type == "'") {
+ // Single quoted strings treat everything as a literal except "\\" and
+ // "\'".
+ return str_replace(
+ array('\\\\', '\\\''),
+ array('\\', "'"),
+ $value);
+ }
+
+ return $this->newStringLiteralFromSemanticString($value);
}
+ return null;
+ }
+
+ private function newStringLiteralFromSemanticString($value) {
// Double quoted strings treat "\X" as a literal if X isn't specifically
// a character which needs to be escaped -- e.g., "\q" and "\'" are
// literally "\q" and "\'". stripcslashes() is too aggressive, so find
// all these under-escaped backslashes and escape them.
+ $len = strlen($value);
+ $esc = false;
+ $out = '';
+
for ($ii = 0; $ii < $len; $ii++) {
$c = $value[$ii];
if ($esc) {

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 5, 11:42 AM (5 d, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225410
Default Alt Text
D21455.diff (3 KB)

Event Timeline