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 @@ -3,10 +3,16 @@ final class XHPASTNode extends AASTNode { public function isStaticScalar() { - return in_array($this->getTypeName(), array( - 'n_STRING_SCALAR', - 'n_NUMERIC_SCALAR', - )); + switch ($this->getTypeName()) { + case 'n_NUMERIC_SCALAR': + return true; + + case 'n_STRING_SCALAR': + return $this->checkIsConstantString(array('n_MAGIC_SCALAR')); + + default: + return false; + } } public function getDocblockToken() { @@ -33,6 +39,12 @@ return $this->getChildByIndex(0)->evalStatic(); break; case 'n_STRING_SCALAR': + if (!$this->checkIsConstantString()) { + throw new Exception( + pht( + 'Non-constant scalar strings cannot be statically evaluated.')); + } + return (string)$this->getStringLiteralValue(); case 'n_NUMERIC_SCALAR': $value = $this->getSemanticString(); @@ -106,14 +118,14 @@ } public function isConstantString() { - return $this->checkIsConstantString(array()); + return $this->checkIsConstantString(); } public function isConstantStringWithMagicConstants() { return $this->checkIsConstantString(array('n_MAGIC_SCALAR')); } - private function checkIsConstantString(array $additional_types) { + private function checkIsConstantString(array $additional_types = array()) { switch ($this->getTypeName()) { case 'n_HEREDOC': case 'n_STRING_SCALAR': diff --git a/src/parser/xhpast/api/__tests__/XHPASTTreeTestCase.php b/src/parser/xhpast/api/__tests__/XHPASTTreeTestCase.php --- a/src/parser/xhpast/api/__tests__/XHPASTTreeTestCase.php +++ b/src/parser/xhpast/api/__tests__/XHPASTTreeTestCase.php @@ -55,9 +55,6 @@ $this->assertEval(0, '0'); - // Static evaluation treats '$' as a literal dollar glyph. - $this->assertEval('$asdf', '"$asdf"'); - $this->assertEval( '\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z'. '\1\2\3\4\5\6\7\8\9\0'.