1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2025-01-01 10:20:58 +01:00

Merge branch "master" into "experimental"

This commit is contained in:
epriestley 2019-02-19 20:57:24 -08:00
commit 2c494385ff
4 changed files with 94 additions and 23 deletions

View file

@ -89,6 +89,9 @@ final class ArcanistDiffUtils extends Phobject {
$highlight_o = '<span class="bright">'; $highlight_o = '<span class="bright">';
$highlight_c = '</span>'; $highlight_c = '</span>';
$depth_in = '<span class="depth-in">';
$depth_out = '<span class="depth-out">';
$is_html = false; $is_html = false;
if ($str instanceof PhutilSafeHTML) { if ($str instanceof PhutilSafeHTML) {
$is_html = true; $is_html = true;
@ -107,11 +110,23 @@ final class ArcanistDiffUtils extends Phobject {
$stack = array_shift($intra_stack); $stack = array_shift($intra_stack);
$s = $e; $s = $e;
$e += $stack[1]; $e += $stack[1];
} while ($stack[0] == 0); } while ($stack[0] === 0);
switch ($stack[0]) {
case '>':
$open_tag = $depth_in;
break;
case '<':
$open_tag = $depth_out;
break;
default:
$open_tag = $highlight_o;
break;
}
} }
if (!$highlight && !$tag && !$ent && $p == $s) { if (!$highlight && !$tag && !$ent && $p == $s) {
$buf .= $highlight_o; $buf .= $open_tag;
$highlight = true; $highlight = true;
} }
@ -139,7 +154,7 @@ final class ArcanistDiffUtils extends Phobject {
if ($tag && $str[$i] == '>') { if ($tag && $str[$i] == '>') {
$tag = false; $tag = false;
if ($highlight) { if ($highlight) {
$buf .= $highlight_o; $buf .= $open_tag;
} }
} }

View file

@ -9,4 +9,4 @@ function f() {
~~~~~~~~~~ ~~~~~~~~~~
warning:3:8 warning:3:8
error:7:1 error:7:1
error:9: error:9:1

View file

@ -26,6 +26,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$whitelist = array( $whitelist = array(
'class' => array(), 'class' => array(),
'function' => array(), 'function' => array(),
'constant' => array(),
); );
$conditionals = $root->selectDescendantsOfType('n_IF'); $conditionals = $root->selectDescendantsOfType('n_IF');
@ -51,6 +52,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
case 'class_exists': case 'class_exists':
case 'function_exists': case 'function_exists':
case 'interface_exists': case 'interface_exists':
case 'defined':
$type = null; $type = null;
switch ($function_name) { switch ($function_name) {
case 'class_exists': case 'class_exists':
@ -64,6 +66,10 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
case 'interface_exists': case 'interface_exists':
$type = 'interface'; $type = 'interface';
break; break;
case 'defined':
$type = 'constant';
break;
} }
$params = $function->getChildOfType(1, 'n_CALL_PARAMETER_LIST'); $params = $function->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
@ -98,7 +104,6 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
// Check if whitelisted.
$whitelisted = false; $whitelisted = false;
foreach (idx($whitelist['function'], $name, array()) as $range) { foreach (idx($whitelist['function'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) { if (array_intersect($range, array_keys($node->getTokens()))) {
@ -178,7 +183,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$version = idx($compat_info['classes'], $name, $version); $version = idx($compat_info['classes'], $name, $version);
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
// Check if whitelisted.
$whitelisted = false; $whitelisted = false;
foreach (idx($whitelist['class'], $name, array()) as $range) { foreach (idx($whitelist['class'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) { if (array_intersect($range, array_keys($node->getTokens()))) {
@ -225,6 +230,18 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
$whitelisted = false;
foreach (idx($whitelist['constant'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) {
$whitelisted = true;
break;
}
}
if ($whitelisted) {
continue;
}
if ($min && version_compare($min, $this->version, '>')) { if ($min && version_compare($min, $this->version, '>')) {
$this->raiseLintAtNode( $this->raiseLintAtNode(
$node, $node,

View file

@ -1852,17 +1852,56 @@ EOTEXT
$this->checkRevisionOwnership(head($result)); $this->checkRevisionOwnership(head($result));
break; break;
case 'reviewers': case 'reviewers':
$untils = array(); $away = array();
foreach ($result as $user) { foreach ($result as $user) {
if (idx($user, 'currentStatus') == 'away') { if (idx($user, 'currentStatus') != 'away') {
$untils[] = $user['currentStatusUntil']; continue;
} }
$username = $user['userName'];
$real_name = $user['realName'];
if (strlen($real_name)) {
$name = pht('%s (%s)', $username, $real_name);
} else {
$name = pht('%s', $username);
} }
if (count($untils) == count($reviewers)) {
$until = date('l, M j Y', min($untils)); $away[] = array(
$confirm = pht( 'name' => $name,
'All reviewers are away until %s. Continue anyway?', 'until' => $user['currentStatusUntil'],
$until); );
}
if ($away) {
if (count($away) == count($reviewers)) {
$earliest_return = min(ipull($away, 'until'));
$message = pht(
'All reviewers are away until %s:',
date('l, M j Y', $earliest_return));
} else {
$message = pht('Some reviewers are currently away:');
}
echo tsprintf(
"%s\n\n",
$message);
$list = id(new PhutilConsoleList());
foreach ($away as $spec) {
$list->addItem(
pht(
'%s (until %s)',
$spec['name'],
date('l, M j Y', $spec['until'])));
}
echo tsprintf(
'%B',
$list->drawConsoleString());
$confirm = pht('Continue even though reviewers are unavailable?');
if (!phutil_console_confirm($confirm)) { if (!phutil_console_confirm($confirm)) {
throw new ArcanistUsageException( throw new ArcanistUsageException(
pht('Specify available reviewers and retry.')); pht('Specify available reviewers and retry.'));