Page MenuHomePhabricator

D21542.id51277.diff
No OneTemporary

D21542.id51277.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -402,6 +402,8 @@
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParenthesesSpacingXHPASTLinterRuleTestCase.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParseStrUseXHPASTLinterRuleTestCase.php',
+ 'ArcanistPartialCatchXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPartialCatchXHPASTLinterRule.php',
+ 'ArcanistPartialCatchXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPartialCatchXHPASTLinterRuleTestCase.php',
'ArcanistPasteRef' => 'ref/paste/ArcanistPasteRef.php',
'ArcanistPasteSymbolRef' => 'ref/paste/ArcanistPasteSymbolRef.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
@@ -1451,6 +1453,8 @@
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
+ 'ArcanistPartialCatchXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistPartialCatchXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPasteRef' => 'ArcanistRef',
'ArcanistPasteSymbolRef' => 'ArcanistSimpleSymbolRef',
'ArcanistPasteWorkflow' => 'ArcanistArcWorkflow',
diff --git a/src/lint/linter/xhpast/rules/ArcanistPartialCatchXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistPartialCatchXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistPartialCatchXHPASTLinterRule.php
@@ -0,0 +1,45 @@
+<?php
+
+final class ArcanistPartialCatchXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 132;
+
+ public function getLintName() {
+ return pht('Partial Catch');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $catch_lists = $root->selectDescendantsOfType('n_CATCH_LIST');
+
+ foreach ($catch_lists as $catch_list) {
+ $catches = $catch_list->getChildrenOfType('n_CATCH');
+
+ $classes = array();
+ foreach ($catches as $catch) {
+ $class_node = $catch->getChildOfType(0, 'n_CLASS_NAME');
+ $class_name = $class_node->getConcreteString();
+ $class_name = phutil_utf8_strtolower($class_name);
+
+ $classes[$class_name] = $class_node;
+ }
+
+ $catches_exception = idx($classes, 'exception');
+ $catches_throwable = idx($classes, 'throwable');
+
+ if ($catches_exception && !$catches_throwable) {
+ $this->raiseLintAtNode(
+ $catches_exception,
+ pht(
+ 'Try/catch block catches "Exception", but does not catch '.
+ '"Throwable". In PHP7 and newer, some runtime exceptions '.
+ 'will escape this block.'));
+ }
+ }
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/ArcanistPartialCatchXHPASTLinterRuleTestCase.php b/src/lint/linter/xhpast/rules/__tests__/ArcanistPartialCatchXHPASTLinterRuleTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/ArcanistPartialCatchXHPASTLinterRuleTestCase.php
@@ -0,0 +1,10 @@
+<?php
+
+final class ArcanistPartialCatchXHPASTLinterRuleTestCase
+ extends ArcanistXHPASTLinterRuleTestCase {
+
+ public function testLinter() {
+ $this->executeTestsInDirectory(dirname(__FILE__).'/partial-catch/');
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/partial-catch/catch-without-throwable.lint-test b/src/lint/linter/xhpast/rules/__tests__/partial-catch/catch-without-throwable.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/partial-catch/catch-without-throwable.lint-test
@@ -0,0 +1,17 @@
+<?php
+try {
+ f();
+} catch (Exception $ex) {
+ g();
+}
+
+try {
+ f();
+} catch (Exception $ex) {
+ g();
+} catch (Throwable $ex) {
+ h();
+}
+
+~~~~~~~~~~
+warning:4:10:XHP132

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 29, 8:25 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7706187
Default Alt Text
D21542.id51277.diff (4 KB)

Event Timeline