diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php --- a/src/lint/linter/ArcanistXHPASTLinter.php +++ b/src/lint/linter/ArcanistXHPASTLinter.php @@ -58,6 +58,7 @@ const LINT_UNNECESSARY_SEMICOLON = 56; const LINT_SELF_MEMBER_REFERENCE = 57; const LINT_LOGICAL_OPERATORS = 58; + const LINT_LOWERCASE_FUNCTIONS = 59; private $blacklistedFunctions = array(); private $naminghook; @@ -129,6 +130,7 @@ self::LINT_UNNECESSARY_SEMICOLON => 'Unnecessary Semicolon', self::LINT_SELF_MEMBER_REFERENCE => 'Self Member Reference', self::LINT_LOGICAL_OPERATORS => 'Logical Operators', + self::LINT_LOWERCASE_FUNCTIONS => 'Lowercase Functions', ); } @@ -175,6 +177,7 @@ self::LINT_UNNECESSARY_SEMICOLON => $advice, self::LINT_SELF_MEMBER_REFERENCE => $advice, self::LINT_LOGICAL_OPERATORS => $advice, + self::LINT_LOWERCASE_FUNCTIONS => $advice, ); } @@ -242,7 +245,7 @@ public function getVersion() { // The version number should be incremented whenever a new rule is added. - return '20'; + return '21'; } protected function resolveFuture($path, Future $future) { @@ -324,6 +327,7 @@ 'lintUnnecessarySemicolons' => self::LINT_UNNECESSARY_SEMICOLON, 'lintSelfMemberReference' => self::LINT_SELF_MEMBER_REFERENCE, 'lintLogicalOperators' => self::LINT_LOGICAL_OPERATORS, + 'lintLowercaseFunctions' => self::LINT_LOWERCASE_FUNCTIONS, ); foreach ($method_codes as $method => $codes) { @@ -3430,6 +3434,39 @@ } } + private function lintLowercaseFunctions(XHPASTNode $root) { + static $builtin_functions = null; + + if ($builtin_functions === null) { + $builtin_functions = array_fuse( + idx(get_defined_functions(), 'internal', array())); + } + + $function_calls = $root->selectDescendantsOfType('n_FUNCTION_CALL'); + + foreach ($function_calls as $function_call) { + $function = $function_call->getChildByIndex(0); + + if ($function->getTypeName() != 'n_SYMBOL_NAME') { + continue; + } + + $function_name = $function->getConcreteString(); + + if (!idx($builtin_functions, strtolower($function_name))) { + continue; + } + + if ($function_name != strtolower($function_name)) { + $this->raiseLintAtNode( + $function, + self::LINT_LOWERCASE_FUNCTIONS, + pht('Calls to built-in PHP functions should be lowercase.'), + strtolower($function_name)); + } + } + } + public function getSuperGlobalNames() { return array( '$GLOBALS', diff --git a/src/lint/linter/__tests__/xhpast/lowercase-functions.lint-test b/src/lint/linter/__tests__/xhpast/lowercase-functions.lint-test new file mode 100644 --- /dev/null +++ b/src/lint/linter/__tests__/xhpast/lowercase-functions.lint-test @@ -0,0 +1,9 @@ +