mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Correct some Arcanist behaviors under PHP8.1
Summary: Ref T13588. See that task for discussion. Improve behavior under PHP8.1, particularly the deprecation warning raised by calling `strlen(null)`. Test Plan: - Ran `arc help`, `arc branches`, `arc diff`, etc., under PHP 8.1 and PHP 7.4. - Created this change with PHP8.1. Maniphest Tasks: T13588 Differential Revision: https://secure.phabricator.com/D21740
This commit is contained in:
parent
13d3a3c3b1
commit
3626582354
12 changed files with 83 additions and 22 deletions
|
@ -181,7 +181,6 @@ final class PhutilErrorHandler extends Phobject {
|
|||
* @task internal
|
||||
*/
|
||||
public static function handleError($num, $str, $file, $line, $ctx = null) {
|
||||
|
||||
foreach (self::$traps as $trap) {
|
||||
$trap->addError($num, $str, $file, $line);
|
||||
}
|
||||
|
@ -378,7 +377,7 @@ final class PhutilErrorHandler extends Phobject {
|
|||
* @task internal
|
||||
*/
|
||||
public static function dispatchErrorMessage($event, $value, $metadata) {
|
||||
$timestamp = strftime('%Y-%m-%d %H:%M:%S');
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
|
||||
switch ($event) {
|
||||
case self::ERROR:
|
||||
|
|
|
@ -212,7 +212,7 @@ abstract class LinesOfALarge extends Phobject implements Iterator {
|
|||
if (strlen($this->buf)) {
|
||||
$this->num++;
|
||||
$this->line = $this->buf;
|
||||
$this->buf = null;
|
||||
$this->buf = '';
|
||||
} else {
|
||||
$this->valid = false;
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
(string)substr($this->stderr, $this->stderrPos),
|
||||
);
|
||||
|
||||
$this->stderrPos = strlen($this->stderr);
|
||||
$this->stderrPos = $this->getStderrBufferLength();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -210,7 +210,8 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
}
|
||||
|
||||
$result = (string)substr($this->stdout, $this->stdoutPos);
|
||||
$this->stdoutPos = strlen($this->stdout);
|
||||
$this->stdoutPos = $this->getStdoutBufferLength();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -475,7 +476,7 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
* @task internal
|
||||
*/
|
||||
public function isReadBufferEmpty() {
|
||||
return !strlen($this->stdout);
|
||||
return !$this->getStdoutBufferLength();
|
||||
}
|
||||
|
||||
|
||||
|
@ -757,14 +758,17 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
$max_stdout_read_bytes = PHP_INT_MAX;
|
||||
$max_stderr_read_bytes = PHP_INT_MAX;
|
||||
if ($read_buffer_size !== null) {
|
||||
$max_stdout_read_bytes = $read_buffer_size - strlen($this->stdout);
|
||||
$max_stderr_read_bytes = $read_buffer_size - strlen($this->stderr);
|
||||
$stdout_len = $this->getStdoutBufferLength();
|
||||
$stderr_len = $this->getStderrBufferLength();
|
||||
|
||||
$max_stdout_read_bytes = $read_buffer_size - $stdout_len;
|
||||
$max_stderr_read_bytes = $read_buffer_size - $stderr_len;
|
||||
}
|
||||
|
||||
if ($max_stdout_read_bytes > 0) {
|
||||
$this->stdout .= $this->readAndDiscard(
|
||||
$stdout,
|
||||
$this->getStdoutSizeLimit() - strlen($this->stdout),
|
||||
$this->getStdoutSizeLimit() - $this->getStdoutBufferLength(),
|
||||
'stdout',
|
||||
$max_stdout_read_bytes);
|
||||
}
|
||||
|
@ -772,7 +776,7 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
if ($max_stderr_read_bytes > 0) {
|
||||
$this->stderr .= $this->readAndDiscard(
|
||||
$stderr,
|
||||
$this->getStderrSizeLimit() - strlen($this->stderr),
|
||||
$this->getStderrSizeLimit() - $this->getStderrBufferLength(),
|
||||
'stderr',
|
||||
$max_stderr_read_bytes);
|
||||
}
|
||||
|
@ -1013,5 +1017,20 @@ final class ExecFuture extends PhutilExecutableFuture {
|
|||
);
|
||||
}
|
||||
|
||||
private function getStdoutBufferLength() {
|
||||
if ($this->stdout === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strlen($this->stdout);
|
||||
}
|
||||
|
||||
private function getStderrBufferLength() {
|
||||
if ($this->stderr === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strlen($this->stderr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -206,12 +206,14 @@ abstract class BaseHTTPFuture extends Future {
|
|||
* @task config
|
||||
*/
|
||||
public function getHeaders($filter = null) {
|
||||
$filter = strtolower($filter);
|
||||
if ($filter !== null) {
|
||||
$filter = phutil_utf8_strtolower($filter);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($this->headers as $header) {
|
||||
list($name, $value) = $header;
|
||||
if (!$filter || ($filter == strtolower($name))) {
|
||||
if (($filter === null) || ($filter === phutil_utf8_strtolower($name))) {
|
||||
$result[] = $header;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,7 +269,7 @@ final class HTTPSFuture extends BaseHTTPFuture {
|
|||
curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, $allowed_protocols);
|
||||
}
|
||||
|
||||
if (strlen($this->rawBody)) {
|
||||
if ($this->rawBody !== null) {
|
||||
if ($this->getData()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
|
|
@ -17,6 +17,14 @@ final class ArcanistCommentStyleXHPASTLinterRule
|
|||
continue;
|
||||
}
|
||||
|
||||
// Don't warn about PHP comment directives. In particular, we need
|
||||
// to use "#[\ReturnTypeWillChange]" to implement "Iterator" in a way
|
||||
// that is compatible with PHP 8.1 and older versions of PHP prior
|
||||
// to the introduction of return types. See T13588.
|
||||
if (preg_match('/^#\\[\\\\/', $value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->raiseLintAtOffset(
|
||||
$comment->getOffset(),
|
||||
pht(
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
class X implements Iterator {
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function reset() {
|
||||
# See T13588 for PHP8.1 compatibility information.
|
||||
}
|
||||
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:7:5:XHP18:Comment Style
|
||||
~~~~~~~~~~
|
||||
<?php
|
||||
|
||||
class X implements Iterator {
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function reset() {
|
||||
// See T13588 for PHP8.1 compatibility information.
|
||||
}
|
||||
|
||||
}
|
|
@ -33,22 +33,27 @@ abstract class Phobject implements Iterator {
|
|||
get_class($this).'::'.$name));
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current() {
|
||||
$this->throwOnAttemptedIteration();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key() {
|
||||
$this->throwOnAttemptedIteration();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next() {
|
||||
$this->throwOnAttemptedIteration();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind() {
|
||||
$this->throwOnAttemptedIteration();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid() {
|
||||
$this->throwOnAttemptedIteration();
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ final class PhutilURI extends Phobject {
|
|||
if ($this->isGitURI()) {
|
||||
$protocol = null;
|
||||
} else {
|
||||
if (strlen($auth)) {
|
||||
if ($auth !== null) {
|
||||
$protocol = nonempty($this->protocol, 'http');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -769,7 +769,12 @@ final class PhutilArgumentParser extends Phobject {
|
|||
pht('There is no **%s** workflow.', $workflow_name));
|
||||
} else {
|
||||
$out[] = $this->indent($indent, $workflow->getExamples());
|
||||
$out[] = $this->indent($indent, $workflow->getSynopsis());
|
||||
|
||||
$synopsis = $workflow->getSynopsis();
|
||||
if ($synopsis !== null) {
|
||||
$out[] = $this->indent($indent, $workflow->getSynopsis());
|
||||
}
|
||||
|
||||
if ($show_details) {
|
||||
$full_help = $workflow->getHelp();
|
||||
if ($full_help) {
|
||||
|
|
|
@ -226,8 +226,8 @@ final class PhutilClassMapQuery extends Phobject {
|
|||
$unique = $this->uniqueMethod;
|
||||
$sort = $this->sortMethod;
|
||||
|
||||
if (strlen($expand)) {
|
||||
if (!strlen($unique)) {
|
||||
if ($expand !== null) {
|
||||
if ($unique === null) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Trying to execute a class map query for descendants of class '.
|
||||
|
@ -245,7 +245,7 @@ final class PhutilClassMapQuery extends Phobject {
|
|||
->loadObjects();
|
||||
|
||||
// Apply the "expand" mechanism, if it is configured.
|
||||
if (strlen($expand)) {
|
||||
if ($expand !== null) {
|
||||
$list = array();
|
||||
foreach ($objects as $object) {
|
||||
foreach (call_user_func(array($object, $expand)) as $instance) {
|
||||
|
@ -257,7 +257,7 @@ final class PhutilClassMapQuery extends Phobject {
|
|||
}
|
||||
|
||||
// Apply the "unique" mechanism, if it is configured.
|
||||
if (strlen($unique)) {
|
||||
if ($unique !== null) {
|
||||
$map = array();
|
||||
foreach ($list as $object) {
|
||||
$key = call_user_func(array($object, $unique));
|
||||
|
@ -287,12 +287,12 @@ final class PhutilClassMapQuery extends Phobject {
|
|||
}
|
||||
|
||||
// Apply the "filter" mechanism, if it is configured.
|
||||
if (strlen($filter)) {
|
||||
if ($filter !== null) {
|
||||
$map = mfilter($map, $filter);
|
||||
}
|
||||
|
||||
// Apply the "sort" mechanism, if it is configured.
|
||||
if (strlen($sort)) {
|
||||
if ($sort !== null) {
|
||||
if ($map) {
|
||||
// The "sort" method may return scalars (which we want to sort with
|
||||
// "msort()"), or may return PhutilSortVector objects (which we want
|
||||
|
|
|
@ -143,7 +143,7 @@ abstract class ArcanistWorkflow extends Phobject {
|
|||
|
||||
if ($information) {
|
||||
$synopsis = $information->getSynopsis();
|
||||
if (strlen($synopsis)) {
|
||||
if ($synopsis !== null) {
|
||||
$phutil_workflow->setSynopsis($synopsis);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue