diff --git a/src/difference/ArcanistDiffUtils.php b/src/difference/ArcanistDiffUtils.php index a68a0532..0f798c9e 100644 --- a/src/difference/ArcanistDiffUtils.php +++ b/src/difference/ArcanistDiffUtils.php @@ -89,6 +89,9 @@ final class ArcanistDiffUtils extends Phobject { $highlight_o = ''; $highlight_c = ''; + $depth_in = ''; + $depth_out = ''; + $is_html = false; if ($str instanceof PhutilSafeHTML) { $is_html = true; @@ -107,11 +110,23 @@ final class ArcanistDiffUtils extends Phobject { $stack = array_shift($intra_stack); $s = $e; $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) { - $buf .= $highlight_o; + $buf .= $open_tag; $highlight = true; } @@ -139,7 +154,7 @@ final class ArcanistDiffUtils extends Phobject { if ($tag && $str[$i] == '>') { $tag = false; if ($highlight) { - $buf .= $highlight_o; + $buf .= $open_tag; } } diff --git a/src/lint/linter/__tests__/jshint/jshint.lint-test b/src/lint/linter/__tests__/jshint/jshint.lint-test index 37c13892..edb1c779 100644 --- a/src/lint/linter/__tests__/jshint/jshint.lint-test +++ b/src/lint/linter/__tests__/jshint/jshint.lint-test @@ -9,4 +9,4 @@ function f() { ~~~~~~~~~~ warning:3:8 error:7:1 -error:9: +error:9:1 diff --git a/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php index b2fa6770..f3dd662e 100644 --- a/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php +++ b/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php @@ -26,6 +26,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule $whitelist = array( 'class' => array(), 'function' => array(), + 'constant' => array(), ); $conditionals = $root->selectDescendantsOfType('n_IF'); @@ -51,6 +52,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule case 'class_exists': case 'function_exists': case 'interface_exists': + case 'defined': $type = null; switch ($function_name) { case 'class_exists': @@ -64,6 +66,10 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule case 'interface_exists': $type = 'interface'; break; + + case 'defined': + $type = 'constant'; + break; } $params = $function->getChildOfType(1, 'n_CALL_PARAMETER_LIST'); @@ -98,7 +104,6 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule $min = idx($version, 'php.min'); $max = idx($version, 'php.max'); - // Check if whitelisted. $whitelisted = false; foreach (idx($whitelist['function'], $name, array()) as $range) { if (array_intersect($range, array_keys($node->getTokens()))) { @@ -178,18 +183,18 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule $version = idx($compat_info['classes'], $name, $version); $min = idx($version, 'php.min'); $max = idx($version, 'php.max'); - // Check if whitelisted. - $whitelisted = false; - foreach (idx($whitelist['class'], $name, array()) as $range) { - if (array_intersect($range, array_keys($node->getTokens()))) { - $whitelisted = true; - break; - } - } - if ($whitelisted) { - continue; + $whitelisted = false; + foreach (idx($whitelist['class'], $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, '>')) { $this->raiseLintAtNode( @@ -225,6 +230,18 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule $min = idx($version, 'php.min'); $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, '>')) { $this->raiseLintAtNode( $node, diff --git a/src/workflow/ArcanistDiffWorkflow.php b/src/workflow/ArcanistDiffWorkflow.php index 28b91a3f..a427846b 100644 --- a/src/workflow/ArcanistDiffWorkflow.php +++ b/src/workflow/ArcanistDiffWorkflow.php @@ -1852,17 +1852,56 @@ EOTEXT $this->checkRevisionOwnership(head($result)); break; case 'reviewers': - $untils = array(); + $away = array(); foreach ($result as $user) { - if (idx($user, 'currentStatus') == 'away') { - $untils[] = $user['currentStatusUntil']; + if (idx($user, 'currentStatus') != 'away') { + continue; } + + $username = $user['userName']; + $real_name = $user['realName']; + + if (strlen($real_name)) { + $name = pht('%s (%s)', $username, $real_name); + } else { + $name = pht('%s', $username); + } + + $away[] = array( + 'name' => $name, + 'until' => $user['currentStatusUntil'], + ); } - if (count($untils) == count($reviewers)) { - $until = date('l, M j Y', min($untils)); - $confirm = pht( - 'All reviewers are away until %s. Continue anyway?', - $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)) { throw new ArcanistUsageException( pht('Specify available reviewers and retry.'));